From bd7c79d28c1fece8308a0437848e71dc8c6e4024 Mon Sep 17 00:00:00 2001 From: Marco Musy Date: Tue, 16 Mar 2021 22:16:58 +0100 Subject: [PATCH] dev --- .gitignore | 7 + README.md | 2 +- docs/changes.md | 5 +- examples/advanced/mesh_smoother1.py | 20 +- examples/basic/mousehighlight.py | 15 +- examples/basic/mousehover.py | 29 +-- examples/basic/rotateImage.py | 22 +- examples/notebooks/README.md | 12 +- examples/notebooks/basic/align1.ipynb | 13 +- examples/notebooks/basic/align2.ipynb | 26 +-- examples/notebooks/basic/sphere.ipynb | 79 +------ .../notebooks/dolfin/demo_cahn-hilliard.ipynb | 139 ------------- examples/notebooks/dolfin/demo_submesh.ipynb | 79 ------- examples/notebooks/dolfin/elasticbeam.ipynb | 83 -------- examples/notebooks/dolfin/ex03_poisson.ipynb | 73 ------- .../notebooks/dolfin/ex04_mixed-poisson.ipynb | 115 ----------- .../notebooks/dolfin/ex06_elasticity2.ipynb | 87 -------- .../dolfin/ex07_stokes-iterative.ipynb | 148 ------------- .../dolfin/ft02_poisson_membrane.ipynb | 103 ---------- .../notebooks/dolfin/magnetostatics.ipynb | 139 ------------- examples/notebooks/dolfin/markmesh.ipynb | 60 ------ examples/notebooks/dolfin/stokes.ipynb | 83 -------- .../notebooks/dolfin/submesh_boundary.ipynb | 71 ------- examples/notebooks/pyplot/latex.ipynb | 62 ------ examples/notebooks/pyplot/plot2_errband.ipynb | 4 +- examples/notebooks/pyplot/quiver.ipynb | 57 ----- examples/notebooks/pyplot/scatter1.ipynb | 58 ------ examples/notebooks/pyplot/scatter2.ipynb | 68 ------ examples/notebooks/pyplot/scatter3.ipynb | 72 ------- .../notebooks/trimesh/first_example.ipynb | 72 ------- examples/notebooks/trimesh/ray.ipynb | 68 ------ examples/notebooks/trimesh/section.ipynb | 79 ------- examples/notebooks/trimesh/shortest.ipynb | 75 ------- examples/other/non_blocking.py | 24 --- examples/volumetric/slicePlane1.py | 20 +- requirements.txt | 2 +- vedo/addons.py | 12 +- vedo/backends.py | 62 +++--- vedo/base.py | 2 +- vedo/docs.py | 4 +- vedo/dolfin.py | 7 +- vedo/io.py | 72 ++++--- vedo/mesh.py | 21 +- vedo/picture.py | 14 ++ vedo/plotter.py | 194 +++++++----------- vedo/pointcloud.py | 14 +- vedo/settings.py | 8 +- vedo/shapes.py | 31 +-- vedo/utils.py | 2 +- vedo/version.py | 2 +- 50 files changed, 303 insertions(+), 2213 deletions(-) delete mode 100644 examples/notebooks/dolfin/demo_cahn-hilliard.ipynb delete mode 100644 examples/notebooks/dolfin/demo_submesh.ipynb delete mode 100644 examples/notebooks/dolfin/elasticbeam.ipynb delete mode 100644 examples/notebooks/dolfin/ex03_poisson.ipynb delete mode 100644 examples/notebooks/dolfin/ex04_mixed-poisson.ipynb delete mode 100644 examples/notebooks/dolfin/ex06_elasticity2.ipynb delete mode 100644 examples/notebooks/dolfin/ex07_stokes-iterative.ipynb delete mode 100644 examples/notebooks/dolfin/ft02_poisson_membrane.ipynb delete mode 100644 examples/notebooks/dolfin/magnetostatics.ipynb delete mode 100644 examples/notebooks/dolfin/markmesh.ipynb delete mode 100644 examples/notebooks/dolfin/stokes.ipynb delete mode 100644 examples/notebooks/dolfin/submesh_boundary.ipynb delete mode 100644 examples/notebooks/pyplot/latex.ipynb delete mode 100644 examples/notebooks/pyplot/quiver.ipynb delete mode 100644 examples/notebooks/pyplot/scatter1.ipynb delete mode 100644 examples/notebooks/pyplot/scatter2.ipynb delete mode 100644 examples/notebooks/pyplot/scatter3.ipynb delete mode 100644 examples/notebooks/trimesh/first_example.ipynb delete mode 100644 examples/notebooks/trimesh/ray.ipynb delete mode 100644 examples/notebooks/trimesh/section.ipynb delete mode 100644 examples/notebooks/trimesh/shortest.ipynb delete mode 100644 examples/other/non_blocking.py diff --git a/.gitignore b/.gitignore index 8b87b978..e07805e4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,10 @@ notebooks/.ipynb_checkpoints/ docs/build/ docs/source/content docs/source/index.rst + +untitled*.py +bug_*.py +prove +speed_tester.py +data + diff --git a/README.md b/README.md index cbb00043..f0b2ca44 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ Type `vedo -h` for the complete list of options.
| [![cubecut](https://user-images.githubusercontent.com/32848391/99916179-e763d580-2d08-11eb-9044-b647115167ed.jpg)](https://github.com/marcomusy/vedo/tree/master/examples/advanced/cutWithMesh2.py) | [![greyscott](https://user-images.githubusercontent.com/32848391/80291855-87e11f80-8751-11ea-9428-12e193a2a66e.gif)](https://github.com/marcomusy/vedo/tree/master/examples/simulations/grayscott.py)| [![quatumsine](https://user-images.githubusercontent.com/32848391/47751431-06aae880-dc92-11e8-9fcf-6659123edbfa.gif)](https://github.com/marcomusy/vedo/tree/master/examples/simulations/tunnelling2.py) | | *Easily work with volumes, tetrahedral and polygonal meshes.* | *Turing system of reaction-diffusion between two molecules.* | *Quantum-tunnelling of a particle in a box hitting a sinusoidal potential.* | | [![trimesh](https://user-images.githubusercontent.com/32848391/91164151-e8b44080-e6ce-11ea-8213-cf5b12aa4d16.png)](https://github.com/marcomusy/vedo/blob/master/examples/other/trimesh) | [![dolf](https://user-images.githubusercontent.com/32848391/58368591-8b3fab80-7eef-11e9-882f-8b8eaef43567.gif)](https://vedo.embl.es/content/vedo/dolfin.html)| [![whisker](https://user-images.githubusercontent.com/32848391/99916183-e8950280-2d08-11eb-8070-8bb1146c7c62.png)](https://github.com/marcomusy/vedo/tree/master/examples/pyplot/whiskers.py) | -| *Interoperability with external libraries like [trimesh](https://trimsh.org/), [pymeshlab](https://github.com/cnr-isti-vclab/PyMeshLab).* | *Support for the [FEniCS/Dolfin](https://fenicsproject.org/) library for PDE and finite element solutions.* | *Advanced 2D/3D histogramming and plotting capablities.* | +| *Interoperability with external libraries like [trimesh](https://trimsh.org/), [pymeshlab](https://github.com/cnr-isti-vclab/PyMeshLab), and [pyvista](https://github.com/pyvista/pyvista).* | *Support for the [FEniCS/Dolfin](https://fenicsproject.org/) library for PDE and finite element solutions.* | *Advanced 2D/3D histogramming and plotting capablities.* | ### Galleries diff --git a/docs/changes.md b/docs/changes.md index bec6949f..8f7aa4e4 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -10,6 +10,7 @@ - Added interfaces and examples to libraries [iminuit](https://github.com/scikit-hep/iminuit) and [pymeshlab](https://github.com/cnr-isti-vclab/PyMeshLab) - variable `datadir` changed to `dataurl` +- added `ipyvtk_simple` for notebooks --- @@ -59,7 +60,7 @@ Lower index means darker. ### `picture.py` - attribute `picture.shape` holds the shape of the picture in pixels - added `gif` file reader to return a list of `Picture` objs. - +- added `clone()` method. --- ### `pointcloud.py` @@ -123,7 +124,9 @@ Lower index means darker. - `vedo -r fitPolynomial1` - `vedo -r fitPolynomial2` - `vedo -r histo_gauss` +- `vedo -r plot_polar` - `vedo -r densifycloud` +- `vedo -r interpolateVolume` diff --git a/examples/advanced/mesh_smoother1.py b/examples/advanced/mesh_smoother1.py index c9036fa3..4f0d12d1 100644 --- a/examples/advanced/mesh_smoother1.py +++ b/examples/advanced/mesh_smoother1.py @@ -1,23 +1,23 @@ """Mesh smoothing with two different methods""" from vedo import Plotter, dataurl -vp = Plotter(N=3) +plt = Plotter(N=3) # Load a mesh and show it -vol = vp.load(dataurl+"embryo.tif") +vol = plt.load(dataurl+"embryo.tif") m0 = vol.isosurface().normalize().lw(0.1).c("violet") -vp.show(m0, __doc__, at=0) +plt.show(m0, __doc__+"\nOriginal Mesh:", at=0) # Adjust mesh using Laplacian smoothing m1 = m0.clone().smoothLaplacian(niter=20, relaxfact=0.1, edgeAngle=15, featureAngle=60) -m1.color("pink").legend("laplacian") -vp.show(m1, at=1) +m1.color("pink") +plt.show(m1, "Laplacian smoothing", at=1, viewup='z') # Adjust mesh using a windowed sinc function interpolation kernel -m2 = m0.clone().smoothWSinc(niter=15, passBand=0.1, edgeAngle=15, featureAngle=60) -m2.color("lg").legend("window sinc") -vp.show(m2, at=2) +m2 = m0.clone().smoothWSinc(niter=20, passBand=0.1, edgeAngle=15, featureAngle=60) +m2.color("lg") +plt.show(m2, "WindowSinc smoothing", at=2) -vp.backgroundColor([0.8, 1, 1], at=0) # set first renderer color +plt.backgroundColor([0.8, 1, 1], at=0) # set first renderer color -vp.show(zoom=1.4, interactive=True) +plt.show(zoom=1.4, interactive=True) diff --git a/examples/basic/mousehighlight.py b/examples/basic/mousehighlight.py index 3eaf3cb2..0a3fca66 100644 --- a/examples/basic/mousehighlight.py +++ b/examples/basic/mousehighlight.py @@ -1,17 +1,24 @@ """Click a sphere to highlight it""" -from vedo import Sphere, Plotter +from vedo import Text2D, Sphere, Plotter import numpy as np -pts = np.random.rand(30,2)*20 -spheres = [Sphere().pos(p).color('k5') for p in pts] +spheres = [] +for i in range(25): + p = np.random.rand(2) + s = Sphere(r=0.05).pos(p).color('k5') + s.name = f"sphere nr.{i} at {p}" + spheres.append(s) def func(evt): if not evt.actor: return sil = evt.actor.silhouette().lineWidth(6).c('red5') + msg.text("You clicked: "+evt.actor.name) plt.remove(silcont.pop()).add(sil) silcont.append(sil) silcont = [None] +msg = Text2D("", pos="bottom-center", c='k', bg='r9', alpha=0.8) + plt = Plotter(axes=1, bg='black') plt.addCallback('mouse click', func) -plt.show(spheres, __doc__, zoom=1.2) +plt.show(spheres, msg, __doc__, zoom=1.2) diff --git a/examples/basic/mousehover.py b/examples/basic/mousehover.py index af449550..36efad57 100644 --- a/examples/basic/mousehover.py +++ b/examples/basic/mousehover.py @@ -1,28 +1,31 @@ """Visualize scalar values interactively by hovering the mouse on a mesh -Press c to clear""" +Press c to clear the path""" from vedo import * -def func(evt): ### called every time the mouse moves! - if not evt.actor: return # no hits, return. (NB: evt is a dictionary) - pt = evt.picked3d # 3d coords of picked point under mouse +def func(evt): ### called every time the mouse moves! + if not evt.actor: return # no hits, return. (NB: evt is a dictionary) + pt = evt.picked3d # 3d coords of picked point under mouse pid = evt.actor.closestPoint(pt, returnPointId=True) - txt = f"Point: {precision(pt[:2],2)}\n" \ - f"Height: {precision(arr[pid],3)}\n"\ + txt = f"Point: {precision(pt[:2] ,2)}\n" \ + f"Height: {precision(arr[pid],3)}\n" \ f"Ground speed: {precision(evt.speed3d*100,2)}" arw = Arrow(pt - evt.delta3d, pt, s=0.001, c='orange5') vig = evt.actor.vignette(txt, point=pt, offset=(0.4,0.6), s=0.04, c='k', font="VictorMono").followCamera() - msg = Text2D(txt, pos='bottom-left', font="VictorMono") - if len(plt.actors) > 3: - plt.remove(plt.actors[-2:]) # remove the old vig and msg - plt.add([arw, vig, msg]) # add Arrow and the new vig and msg + msg.text(txt) # update text message + if len(plt.actors)>3: + plt.pop() # remove the old vignette + plt.add([arw, vig]) # add Arrow and the new vig hil = ParametricShape('RandomHills').cmap('terrain').addScalarBar() arr = hil.getPointArray("Scalars") plt = Plotter(axes=1, bg2='lightblue') -plt.addCallback('MouseMove', func) # the callback function -plt.addCallback('KeyPress', lambda e: plt.remove(plt.actors[2:], render=True)) -plt.show(hil, __doc__, viewup='z') +plt.addCallback('mouse moving', func) # the callback function +plt.addCallback('keyboard', lambda e: plt.remove(plt.actors[3:], render=True)) + +msg = Text2D("", pos='bottom-left', font="VictorMono") + +plt.show(hil, msg, __doc__, viewup='z') diff --git a/examples/basic/rotateImage.py b/examples/basic/rotateImage.py index db155413..98c2354d 100644 --- a/examples/basic/rotateImage.py +++ b/examples/basic/rotateImage.py @@ -1,15 +1,17 @@ """Normal jpg/png pictures can be loaded, -cropped, rotated and positioned in 3D -""" -from vedo import Plotter, dataurl +cropped, rotated and positioned in 3D.""" +from vedo import Plotter, Picture, dataurl -vp = Plotter(axes=3) +plt = Plotter(axes=7) + +pic = Picture(dataurl+"images/dog.jpg") for i in range(5): - p = vp.load(dataurl+"images/dog.jpg") # returns Picture - p.crop(bottom=0.2) # crop 20% - p.scale(1-i/10.0).alpha(0.8) # picture can be scaled in size - p.rotateX(20*i).pos(0,0,30*i) # (can concatenate methods) + p = pic.clone() + p.crop(bottom=0.20) # crop 20% from bottom + p.scale(1-i/10.0).rotateX(20*i).z(30*i) + p.alpha(0.8) + plt += p -vp += __doc__ -vp.show() +plt += __doc__ +plt.show() diff --git a/examples/notebooks/README.md b/examples/notebooks/README.md index 2853507c..0b4f4a51 100644 --- a/examples/notebooks/README.md +++ b/examples/notebooks/README.md @@ -1,14 +1,16 @@ # Jupyter Notebooks -Here you will find a set of notebooks. -It allows to embed a redering window into a jupyter notebook via +Here you will find a set of notebooks. +It allows to embed a redering window into a jupyter notebook via [K3D](https://github.com/K3D-tools/K3D-jupyter) -(or optionally with `itkwidgets` or [panel](https://github.com/pyviz/panel)). +(or optionally with `itkwidgets`, `ipyvtk` or [panel](https://github.com/pyviz/panel)). On top of this `K3D` allows to export an interactive [snapshot](https://vedo.embl.es/examples/K3D_snapshot.html) of the rendered scene. -`jupyter notebook examples/notebooks/basic/embryo.ipynb` +### note that notebook support (except for `ipyvtk`) is rather limited and not all functionalities are available, in particular: -![embed](https://user-images.githubusercontent.com/32848391/58486800-d6172880-8166-11e9-9a43-ed20b8fed19c.jpg) +- axes are very basic +- text2d is not available +- limited possibilities for scene interaction diff --git a/examples/notebooks/basic/align1.ipynb b/examples/notebooks/basic/align1.ipynb index 0d1e7ea6..14230ff7 100644 --- a/examples/notebooks/basic/align1.ipynb +++ b/examples/notebooks/basic/align1.ipynb @@ -3,7 +3,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [], "source": [ "\"\"\"\n", @@ -14,7 +16,7 @@ "\"\"\"\n", "from vedo import *\n", "\n", - "embedWindow('k3d') # or panel, k3d, itk, ipyvtk, or False\n", + "embedWindow(\"k3d\") # or panel, k3d, itk, ipyvtk, or False\n", "\n", "plt = Plotter()\n", "\n", @@ -34,13 +36,6 @@ "printc([arim.getTransform()], invert=True)\n", "plt.show(axes=1)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/examples/notebooks/basic/align2.ipynb b/examples/notebooks/basic/align2.ipynb index 5ca3354d..476d4bb2 100644 --- a/examples/notebooks/basic/align2.ipynb +++ b/examples/notebooks/basic/align2.ipynb @@ -2,24 +2,9 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "0a54c302d3a04861854eea7ad62f5bc1", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Plot(antialias=3, axes=['x', 'y', 'z'], axes_helper=1.0, background_color=16777215, camera=[2, -3, 0.2, 0.0, 0…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "\"\"\"Example usage of align() method:\n", "generate two random sets of points and align them using\n", @@ -54,13 +39,6 @@ "vp.show()" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": null, diff --git a/examples/notebooks/basic/sphere.ipynb b/examples/notebooks/basic/sphere.ipynb index 4580332c..c004e1d8 100644 --- a/examples/notebooks/basic/sphere.ipynb +++ b/examples/notebooks/basic/sphere.ipynb @@ -2,29 +2,13 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1c3612b7f22e457685d803362ca4b53a", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "ViewInteractiveWidget(height=960, layout=Layout(height='auto', width='100%'), width=960)" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "from vedo import *\n", "\n", - "embedWindow('ipyvtk') #uncomment to pop an ext. window\n", - "\n", + "embedWindow('ipyvtk') \n", "\n", "s = Sphere().cutWithPlane(normal=(1,1,1))\n", "scals = s.points()[:,2] # use z-coords to color vertices\n", @@ -32,68 +16,25 @@ "# NB, actions can be concatenated into a pipeline:\n", "# add point scalars with a choice of color map, use flat shading, print infos and then show\n", "s.cmap('Set3', scals)\n", - "plt = s.show(axes=1, viewup='z')\n", - "plt" + "s.show(axes=1, viewup='z')" ] }, { "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "closeWindow()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "settings.plotter_instance.backgroundColor('g','y')" + "settings.plotter_instance.backgroundColor('lg','lb')" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "settings.plotter_instance.add(\"gggg\")" + "settings.plotter_instance.add(\"some message\")" ] }, { diff --git a/examples/notebooks/dolfin/demo_cahn-hilliard.ipynb b/examples/notebooks/dolfin/demo_cahn-hilliard.ipynb deleted file mode 100644 index 3d369d9e..00000000 --- a/examples/notebooks/dolfin/demo_cahn-hilliard.ipynb +++ /dev/null @@ -1,139 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "\"\"\"Solution of a particular nonlinear time-dependent \n", - "fourth-order equation, known as the Cahn-Hilliard equation.\"\"\"\n", - "import random\n", - "from dolfin import *\n", - "set_log_level(30)\n", - "\n", - "# Class representing the intial conditions\n", - "class InitialConditions(UserExpression):\n", - " def __init__(self, **kwargs):\n", - " random.seed(2 + MPI.rank(MPI.comm_world))\n", - " super().__init__(**kwargs)\n", - " def eval(self, values, x):\n", - " values[0] = 0.63 + 0.02 * (0.5 - random.random())\n", - " values[1] = 0.0\n", - " def value_shape(self): return (2,)\n", - "\n", - "# Class for interfacing with the Newton solver\n", - "class CahnHilliardEquation(NonlinearProblem):\n", - " def __init__(self, a, L):\n", - " NonlinearProblem.__init__(self)\n", - " self.L = L\n", - " self.a = a\n", - " def F(self, b, x): assemble(self.L, tensor=b)\n", - " def J(self, A, x): assemble(self.a, tensor=A)\n", - "\n", - "# Model parameters\n", - "lmbda = 1.0e-02 # surface parameter\n", - "dt = 5.0e-06 # time step\n", - "# time stepping family, \n", - "# e.g. theta=1 -> backward Euler, theta=0.5 -> Crank-Nicolson\n", - "theta = 0.5\n", - "\n", - "# Form compiler options\n", - "parameters[\"form_compiler\"][\"optimize\"] = True\n", - "parameters[\"form_compiler\"][\"cpp_optimize\"] = True\n", - "\n", - "# Create mesh and define function spaces\n", - "mesh = UnitSquareMesh(60, 60)\n", - "# mesh = UnitSquareMesh.create(60, 60, CellType.Type.triangle)\n", - "# V = FunctionSpace(mesh, \"Lagrange\", 1)\n", - "P1 = FiniteElement(\"Lagrange\", mesh.ufl_cell(), 1)\n", - "ME = FunctionSpace(mesh, P1 * P1)\n", - "\n", - "# Define trial and test functions\n", - "du = TrialFunction(ME)\n", - "q, v = TestFunctions(ME)\n", - "\n", - "# Define functions\n", - "u = Function(ME) # current solution\n", - "u0 = Function(ME) # solution from previous converged step\n", - "\n", - "# Split mixed functions\n", - "dc, dmu = split(du)\n", - "c, mu = split(u)\n", - "c0, mu0 = split(u0)\n", - "\n", - "# Create intial conditions and interpolate\n", - "u_init = InitialConditions(degree=1)\n", - "u.interpolate(u_init)\n", - "u0.interpolate(u_init)\n", - "\n", - "# Compute the chemical potential df/dc\n", - "c = variable(c)\n", - "f = 100 * c ** 2 * (1 - c) ** 2\n", - "mu_mid = (1 - theta) * mu0 + theta * mu\n", - "\n", - "# Weak statement of the equations\n", - "L0 = c * q - c0 * q + dt * dot(grad(mu_mid), grad(q))\n", - "L1 = mu * v - diff(f, c) * v - lmbda * dot(grad(c), grad(v))\n", - "L = (L0 + L1) * dx\n", - "\n", - "# Compute directional derivative about u in the direction of du\n", - "a = derivative(L, u, du)\n", - "\n", - "# Create nonlinear problem and Newton solver\n", - "problem = CahnHilliardEquation(a, L)\n", - "solver = NewtonSolver()\n", - "solver.parameters[\"linear_solver\"] = \"lu\"\n", - "solver.parameters[\"convergence_criterion\"] = \"incremental\"\n", - "solver.parameters[\"relative_tolerance\"] = 1e-6\n", - "\n", - "# Step in time\n", - "from vedo.dolfin import *\n", - "\n", - "# embedWindow('itkwidgets') # backends are: itkwidgets, k3d or False\n", - "\n", - "t = 0\n", - "pb = ProgressBar(0,10)\n", - "for i in pb.range():\n", - " t += dt\n", - " u0.vector()[:] = u.vector()\n", - " solver.solve(problem, u.vector())\n", - " \n", - " plt = plot(u.split()[0], z=i*0.1, add=True) # do not clear the canvas\n", - " pb.print()\n", - " \n", - "plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/demo_submesh.ipynb b/examples/notebooks/dolfin/demo_submesh.ipynb deleted file mode 100644 index d08bce3a..00000000 --- a/examples/notebooks/dolfin/demo_submesh.ipynb +++ /dev/null @@ -1,79 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "How to extract matching sub meshes from a common mesh.\n", - "\"\"\"\n", - "from dolfin import *\n", - "\n", - "class Structure(SubDomain):\n", - " def inside(self, x, on_boundary):\n", - " return x[0] > 1.4 - DOLFIN_EPS and x[0] < 1.6 \\\n", - " + DOLFIN_EPS and x[1] < 0.6 + DOLFIN_EPS\n", - "\n", - "mesh = RectangleMesh(Point(0.0, 0.0), Point(3.0, 1.0), 60, 20)\n", - "\n", - "# Create sub domain markers and mark everaything as 0\n", - "sub_domains = MeshFunction(\"size_t\", mesh, mesh.topology().dim())\n", - "sub_domains.set_all(0)\n", - "\n", - "# Mark structure domain as 1\n", - "structure = Structure()\n", - "structure.mark(sub_domains, 1)\n", - "\n", - "# Extract sub meshes\n", - "fluid_mesh = SubMesh(mesh, sub_domains, 0)\n", - "structure_mesh = SubMesh(mesh, sub_domains, 1)\n", - "\n", - "# Move structure mesh\n", - "for x in structure_mesh.coordinates():\n", - " x[0] += 0.1*x[0]*x[1]\n", - "\n", - "# Move fluid mesh according to structure mesh\n", - "ALE.move(fluid_mesh, structure_mesh)\n", - "fluid_mesh.smooth()\n", - "\n", - "#############################################\n", - "from vedo.dolfin import *\n", - "\n", - "# embedWindow('itkwidgets') # backends are: itkwidgets, k3d or False\n", - "\n", - "plot(fluid_mesh)\n", - "plot(structure_mesh, c='tomato', add=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/elasticbeam.ipynb b/examples/notebooks/dolfin/elasticbeam.ipynb deleted file mode 100644 index 8dac8c58..00000000 --- a/examples/notebooks/dolfin/elasticbeam.ipynb +++ /dev/null @@ -1,83 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"A beam deforming under its own weight.\"\"\"\n", - "from dolfin import *\n", - "\n", - "# Scaled variables\n", - "l, w = 1, 0.1\n", - "mu_, lambda_ = 1, 1\n", - "rho = 10\n", - "gamma = (w/l)**2\n", - "wind = (0, 0.0, 0)\n", - "\n", - "# Create mesh and define function space\n", - "mesh = BoxMesh(Point(0, 0, 0), Point(l, w, w), 50, 5, 5)\n", - "V = VectorFunctionSpace(mesh, \"P\", 1)\n", - "\n", - "# Define boundary condition\n", - "def clamped_boundary(x, on_boundary):\n", - " return on_boundary and (near(x[0], 0) or near(x[0], l))\n", - "bc = DirichletBC(V, Constant((0, 0, 0)), clamped_boundary)\n", - "\n", - "# Define strain and stress\n", - "def epsilon(u):\n", - " return 0.5 * (nabla_grad(u) + nabla_grad(u).T)\n", - "\n", - "def sigma(u):\n", - " return lambda_ * nabla_grad(u) * Identity(3) + 2 * mu_ * epsilon(u)\n", - "\n", - "# Define variational problem\n", - "u = TrialFunction(V)\n", - "v = TestFunction(V)\n", - "f = Constant((0, 0, -rho * gamma))\n", - "T = Constant(wind)\n", - "a = inner(sigma(u), epsilon(v)) * dx\n", - "L = dot(f, v) * dx + dot(T, v) * ds\n", - "\n", - "# Compute solution\n", - "u = Function(V)\n", - "solve(a == L, u, bc)\n", - "\n", - "\n", - "################################ Plot solution\n", - "from vedo.dolfin import *\n", - "\n", - "plot(u, mode=\"displaced mesh\", shading='flat')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/ex03_poisson.ipynb b/examples/notebooks/dolfin/ex03_poisson.ipynb deleted file mode 100644 index d75f2eb0..00000000 --- a/examples/notebooks/dolfin/ex03_poisson.ipynb +++ /dev/null @@ -1,73 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "Poisson equation with Dirichlet conditions.\n", - "\n", - " -Laplace(u) = f in the unit square\n", - " u = uD on the boundary\n", - "\n", - " uD = 1 + x^2 + 2*y^2\n", - " (f = -6)\n", - "\"\"\"\n", - "########################################################### fenics\n", - "from fenics import *\n", - "\n", - "# Create mesh and define function space\n", - "mesh = UnitSquareMesh(8, 8)\n", - "V = FunctionSpace(mesh, \"P\", 1)\n", - "\n", - "# Define boundary condition\n", - "uD = Expression(\"1 + x[0]*x[0] + 2*x[1]*x[1]\", degree=2)\n", - "bc = DirichletBC(V, uD, \"on_boundary\")\n", - "\n", - "# Define variational problem\n", - "w = TrialFunction(V)\n", - "v = TestFunction(V)\n", - "u = Function(V)\n", - "f = Constant(-6.0)\n", - "\n", - "# Compute solution\n", - "solve( dot(grad(w), grad(v))*dx == f*v*dx, u, bc)\n", - "\n", - "########################################################### vedo\n", - "from vedo.dolfin import plot\n", - "\n", - "plot(u, cmap='magma')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/ex04_mixed-poisson.ipynb b/examples/notebooks/dolfin/ex04_mixed-poisson.ipynb deleted file mode 100644 index 40061687..00000000 --- a/examples/notebooks/dolfin/ex04_mixed-poisson.ipynb +++ /dev/null @@ -1,115 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "754e3e6bf0e346ea9cbf2c6e01d8a663", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Viewer(cmap='jet', geometries=[{'vtkClass': 'vtkPolyData', 'points': {'vtkClass': 'vtkPoints', 'name': '_point…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\"\"\"\n", - "Solving Poisson equation using\n", - "a mixed (two-field) formulation.\n", - "\"\"\"\n", - "# needs python3\n", - "# https://fenicsproject.org/docs/dolfin/2018.1.0/python/demos/mixed-poisson\n", - "from dolfin import *\n", - "\n", - "# Create mesh\n", - "mesh = UnitSquareMesh(30, 30)\n", - "\n", - "# Define finite elements spaces and build mixed space\n", - "BDM = FiniteElement(\"BDM\", mesh.ufl_cell(), 1)\n", - "DG = FiniteElement(\"DG\", mesh.ufl_cell(), 0)\n", - "W = FunctionSpace(mesh, BDM * DG)\n", - "\n", - "# Define trial and test functions\n", - "(sigma, u) = TrialFunctions(W)\n", - "(tau, v) = TestFunctions(W)\n", - "\n", - "# Define source function\n", - "f = Expression(\"10*exp(-(pow(x[0]-0.5, 2) + pow(x[1]-0.5, 2))/0.02)\", degree=2)\n", - "\n", - "# Define variational form\n", - "a = (dot(sigma, tau) + div(tau) * u + div(sigma) * v) * dx\n", - "L = -f * v * dx\n", - "\n", - "# Define function G such that G \\cdot n = g\n", - "class BoundarySource(UserExpression):\n", - " def __init__(self, mesh, **kwargs):\n", - " self.mesh = mesh\n", - " super().__init__(**kwargs)\n", - " def eval_cell(self, values, x, ufc_cell):\n", - " cell = Cell(self.mesh, ufc_cell.index)\n", - " n = cell.normal(ufc_cell.local_facet)\n", - " g = sin(5 * x[0])\n", - " values[0] = g * n[0]\n", - " values[1] = g * n[1]\n", - " def value_shape(self):\n", - " return (2,)\n", - "G = BoundarySource(mesh, degree=2)\n", - "\n", - "# Define essential boundary\n", - "def boundary(x):\n", - " return x[1] < DOLFIN_EPS or x[1] > 1.0 - DOLFIN_EPS\n", - "bc = DirichletBC(W.sub(0), G, boundary)\n", - "\n", - "# Compute solution\n", - "w = Function(W)\n", - "solve(a == L, w, bc)\n", - "(sigma, u) = w.split()\n", - "\n", - "\n", - "########################################################### vedo\n", - "from vedo.dolfin import *\n", - "\n", - "embedWindow('itkwidgets') # backends are: itkwidgets, k3d or False\n", - "\n", - "# Plot solution on mesh, and warp z-axis by the scalar value\n", - "plot(u, warpZfactor=1.0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/ex06_elasticity2.ipynb b/examples/notebooks/dolfin/ex06_elasticity2.ipynb deleted file mode 100644 index cf3cffec..00000000 --- a/examples/notebooks/dolfin/ex06_elasticity2.ipynb +++ /dev/null @@ -1,87 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1bb7c5ac53c3424799802720c81a54d8", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Plot(antialias=3, axes=['x', 'y', 'z'], background_color=16777215, camera=[0.5197843715148425, 0.5197843715148…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\"\"\"Show fenics mesh and displacement solution.\"\"\"\n", - "########################################################### dolfin\n", - "from dolfin import *\n", - "\n", - "# Create mesh and define function space\n", - "mesh = UnitCubeMesh(12, 12, 12)\n", - "V = VectorFunctionSpace(mesh, \"Lagrange\", 1)\n", - "\n", - "# Mark boundary subdomains\n", - "left = CompiledSubDomain(\"near(x[0], side) && on_boundary\", side=0.0)\n", - "right = CompiledSubDomain(\"near(x[0], side) && on_boundary\", side=1.0)\n", - "\n", - "# Define Dirichlet boundary (x=0 or x=1)\n", - "c = Constant((0.0, 0.0, 0.0))\n", - "r = Expression((\n", - " \"scale*0.0\",\n", - " \"scale*(y0 + (x[1]-y0)*cos(theta) - (x[2]-z0)*sin(theta)-x[1])\",\n", - " \"scale*(z0 + (x[1]-y0)*sin(theta) + (x[2]-z0)*cos(theta)-x[2])\",\n", - " ), scale=0.5, y0=0.5, z0=0.5, theta=pi/4, degree=2 )\n", - "bcl = DirichletBC(V, c, left)\n", - "bcr = DirichletBC(V, r, right)\n", - "\n", - "w = TrialFunction(V) # Incremental displacement\n", - "v = TestFunction(V) # Test function\n", - "u = Function(V) # Solution\n", - "\n", - "solve(inner(grad(w), grad(v)) * dx == inner(c, v) * dx, u, [bcl, bcr])\n", - "\n", - "########################################################### vedo\n", - "from vedo.dolfin import plot\n", - "\n", - "plot(u, mode='my displaced mesh please!!', shading='flat', cmap='jet')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/ex07_stokes-iterative.ipynb b/examples/notebooks/dolfin/ex07_stokes-iterative.ipynb deleted file mode 100644 index e9e75389..00000000 --- a/examples/notebooks/dolfin/ex07_stokes-iterative.ipynb +++ /dev/null @@ -1,148 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m(logscale) pressure histogram\t(entries=729)\n", - "2.16 ▉ \n", - " | ▉▉ \n", - " | ▉▉▉▉\n", - " | ▉ ▉ ▉▉▉▉▉▉\n", - " | ▉▉ ▉▉▉▉▉▉▉▉▉▉\n", - " | ▉▉▉ ▉▉▉▉▉▉▉▉▉▉\n", - " | ▉ ▉▉ ▉▉▉▉▉▉▉▉▉▉▉▉▉▉\n", - " | ▉▉▉▉▉ ▉▉▉▉▉▉▉▉▉▉▉▉▉▉\n", - " | ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉\n", - " | ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉\n", - "-6.52....................0.28\n", - "\u001b[0m\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "3d3459e6f77148a28cc787bf2dc12d4d", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Plot(antialias=3, axes=['x', 'y', 'z'], axes_helper=1.0, background_color=16777215, camera=[0.5173205080756887…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\"\"\"\n", - "Stokes equations with an iterative solver.\n", - "\"\"\"\n", - "# https://fenicsproject.org/docs/dolfin/2018.1.0/python/demos/\n", - "# stokes-iterative/demo_stokes-iterative.py.html\n", - "from dolfin import *\n", - "\n", - "mesh = UnitCubeMesh(8, 8, 8)\n", - "\n", - "# Build function space\n", - "P2 = VectorElement(\"Lagrange\", mesh.ufl_cell(), 2)\n", - "P1 = FiniteElement(\"Lagrange\", mesh.ufl_cell(), 1)\n", - "TH = P2 * P1\n", - "W = FunctionSpace(mesh, TH)\n", - "\n", - "# Boundaries\n", - "def right(x, on_boundary):\n", - " return x[0] > (1.0 - DOLFIN_EPS)\n", - "\n", - "def left(x, on_boundary):\n", - " return x[0] < DOLFIN_EPS\n", - "\n", - "def top_bottom(x, on_boundary):\n", - " return x[1] > 1.0 - DOLFIN_EPS or x[1] < DOLFIN_EPS\n", - "\n", - "# No-slip boundary condition for velocity\n", - "noslip = Constant((0.0, 0.0, 0.0))\n", - "bc0 = DirichletBC(W.sub(0), noslip, top_bottom)\n", - "\n", - "# Inflow boundary condition for velocity\n", - "inflow = Expression((\"-sin(x[1]*pi)\", \"0.0\", \"0.0\"), degree=2)\n", - "bc1 = DirichletBC(W.sub(0), inflow, right)\n", - "\n", - "# Define variational problem\n", - "(u, p) = TrialFunctions(W)\n", - "(v, q) = TestFunctions(W)\n", - "f = Constant((0.0, 0.0, 0.0))\n", - "a = inner(grad(u), grad(v)) * dx + div(v) * p * dx + q * div(u) * dx\n", - "L = inner(f, v) * dx\n", - "\n", - "# Form for use in constructing preconditioner matrix\n", - "b = inner(grad(u), grad(v)) * dx + p * q * dx\n", - "\n", - "# Assemble system\n", - "A, bb = assemble_system(a, L, [bc0, bc1])\n", - "\n", - "# Assemble preconditioner system\n", - "P, btmp = assemble_system(b, L, [bc0, bc1])\n", - "\n", - "# Create Krylov solver and AMG preconditioner\n", - "if has_krylov_solver_method(\"minres\"):\n", - " krylov_method = \"minres\"\n", - "elif has_krylov_solver_method(\"tfqmr\"):\n", - " krylov_method = \"tfqmr\"\n", - "solver = KrylovSolver(krylov_method, \"amg\")\n", - "\n", - "# Associate operator (A) and preconditioner matrix (P)\n", - "solver.set_operators(A, P)\n", - "\n", - "# Solve\n", - "U = Function(W)\n", - "solver.solve(U.vector(), bb)\n", - "\n", - "# Get sub-functions\n", - "u, p = U.split()\n", - "pressures = p.compute_vertex_values(mesh)\n", - "\n", - "\n", - "#################################################### vedo\n", - "from vedo.dolfin import plot, printHistogram\n", - "\n", - "printHistogram(pressures, title='pressure histogram', logscale=True)\n", - "\n", - "plot(u, wireframe=1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/ft02_poisson_membrane.ipynb b/examples/notebooks/dolfin/ft02_poisson_membrane.ipynb deleted file mode 100644 index 6286206c..00000000 --- a/examples/notebooks/dolfin/ft02_poisson_membrane.ipynb +++ /dev/null @@ -1,103 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "c5664dba853d48baa864a7dab1d9fc72", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Plot(antialias=3, axes=['x', 'y', 'z'], axes_helper=1.0, background_color=16777215, camera=[0.0283442240352957…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\"\"\"Deflection of a membrane.\n", - "\n", - " -Laplace(w) = p in the unit circle\n", - " w = 0 on the boundary\n", - "\n", - "The load p is a Gaussian function centered at (0, 0.6).\"\"\"\n", - "from fenics import *\n", - "from mshr import Circle, generate_mesh\n", - "\n", - "# Create mesh and define function space\n", - "domain = Circle(Point(0, 0), 1)\n", - "mesh = generate_mesh(domain, 64)\n", - "V = FunctionSpace(mesh, 'P', 2)\n", - "w_D = Constant(0)\n", - "\n", - "def boundary(x, on_boundary):\n", - " return on_boundary\n", - "bc = DirichletBC(V, w_D, boundary)\n", - "\n", - "# Define load\n", - "p = Expression('4*exp(-pow(beta, 2)*(pow(x[0], 2) + pow(x[1] - R0, 2)))', degree=1, beta=8, R0=0.6)\n", - "\n", - "# Define variational problem\n", - "w = TrialFunction(V)\n", - "v = TestFunction(V)\n", - "a = dot(grad(w), grad(v))*dx\n", - "L = p*v*dx\n", - "\n", - "# Compute solution\n", - "w = Function(V)\n", - "solve(a == L, w, bc)\n", - "\n", - "p = interpolate(p, V)\n", - "\n", - "# Curve plot along x = 0 comparing p and w\n", - "import numpy as np\n", - "tol = 0.001 # avoid hitting points outside the domain\n", - "y = np.linspace(-1 + tol, 1 - tol, 101)\n", - "points = [(0, y_) for y_ in y] # 2D points\n", - "w_line = np.array([w(point) for point in points])\n", - "\n", - "#######################################################################\n", - "from vedo.dolfin import plot\n", - "from vedo import Line\n", - "\n", - "wline = Line(y, w_line*10, c='k', lw=8).z(0.01)\n", - "\n", - "plot(w, wline) #deflection" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/magnetostatics.ipynb b/examples/notebooks/dolfin/magnetostatics.ipynb deleted file mode 100644 index 8da0adb4..00000000 --- a/examples/notebooks/dolfin/magnetostatics.ipynb +++ /dev/null @@ -1,139 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING: user expression has not supplied value_shape method or an element. Assuming scalar element.\n" - ] - } - ], - "source": [ - "\"\"\"Compute the magnetic field B in an iron cylinder, the copper wires, and the surrounding vacuum.\"\"\"\n", - "# https://fenicsproject.org/pub/tutorial/html/._ftut1015.html\n", - "from fenics import *\n", - "from mshr import *\n", - "from math import sin, cos, pi\n", - "\n", - "a = 1.0 # inner radius of iron cylinder\n", - "b = 1.2 # outer radius of iron cylinder\n", - "c_1 = 0.8 # radius for inner circle of copper wires\n", - "c_2 = 1.4 # radius for outer circle of copper wires\n", - "r = 0.1 # radius of copper wires\n", - "R = 2.5 # radius of domain\n", - "n = 5 # number of windings\n", - "\n", - "# Define geometry for background\n", - "domain = Circle(Point(0, 0), R)\n", - "\n", - "# Define geometry for iron cylinder\n", - "cylinder = Circle(Point(0, 0), b) - Circle(Point(0, 0), a)\n", - "\n", - "# Define geometry for wires (N = North (up), S = South (down))\n", - "angles_N = [i*2*pi/n for i in range(n)]\n", - "angles_S = [(i + 0.5)*2*pi/n for i in range(n)]\n", - "wires_N = [Circle(Point(c_1*cos(v), c_1*sin(v)), r) for v in angles_N]\n", - "wires_S = [Circle(Point(c_2*cos(v), c_2*sin(v)), r) for v in angles_S]\n", - "\n", - "# Set subdomain for iron cylinder\n", - "domain.set_subdomain(1, cylinder)\n", - "\n", - "# Set subdomains for wires\n", - "for (i, wire) in enumerate(wires_N):\n", - " domain.set_subdomain(2 + i, wire)\n", - "for (i, wire) in enumerate(wires_S):\n", - " domain.set_subdomain(2 + n + i, wire)\n", - "\n", - "# Create mesh\n", - "mesh = generate_mesh(domain, 64)\n", - "\n", - "# Define function space\n", - "V = FunctionSpace(mesh, 'P', 1)\n", - "\n", - "# Define boundary condition\n", - "bc = DirichletBC(V, Constant(0), 'on_boundary')\n", - "\n", - "# Define subdomain markers and integration measure\n", - "markers = MeshFunction('size_t', mesh, 2, mesh.domains())\n", - "dx = Measure('dx', domain=mesh, subdomain_data=markers)\n", - "\n", - "# Define current densities\n", - "J_N = Constant(1.0)\n", - "J_S = Constant(-1.0)\n", - "\n", - " \n", - "# Define magnetic permeability\n", - "class Permeability(UserExpression):\n", - " def __init__(self, markers, **kwargs):\n", - " self.markers = markers\n", - " super().__init__(**kwargs)\n", - " def eval_cell(self, values, x, cell):\n", - " if self.markers[cell.index] == 0:\n", - " values[0] = 4*pi*1e-7 # vacuum\n", - " elif self.markers[cell.index] == 1:\n", - " values[0] = 1e-5 # iron (should really be 6.3e-3)\n", - " else:\n", - " values[0] = 1.26e-6 # copper\n", - "mu = Permeability(markers, degree=1)\n", - "\n", - "# Define variational problem\n", - "A_z = TrialFunction(V)\n", - "v = TestFunction(V)\n", - "a = (1 / mu)*dot(grad(A_z), grad(v))*dx\n", - "L_N = sum(J_N*v*dx(i) for i in range(2, 2 + n))\n", - "L_S = sum(J_S*v*dx(i) for i in range(2 + n, 2 + 2*n))\n", - "L = L_N + L_S\n", - "\n", - "# Solve variational problem\n", - "A_z = Function(V)\n", - "solve(a == L, A_z, bc)\n", - "\n", - "# Plot solution\n", - "from vedo.dolfin import plot\n", - "plot(A_z,\n", - " #isolines={'n':10, 'lw':1.5, 'c':'black'} #not yet working\n", - " )\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/markmesh.ipynb b/examples/notebooks/dolfin/markmesh.ipynb deleted file mode 100644 index 04f2e5bb..00000000 --- a/examples/notebooks/dolfin/markmesh.ipynb +++ /dev/null @@ -1,60 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''Mark mesh with boundary function.'''\n", - "from dolfin import *\n", - "\n", - "mesh = UnitCubeMesh(5,5,5)\n", - "V = FunctionSpace(mesh, \"Lagrange\", 1)\n", - "\n", - "class left(SubDomain):\n", - " def inside(self, x, on_boundary):\n", - " return on_boundary and abs(x[0]) < DOLFIN_EPS\n", - "left = left()\n", - "\n", - "tcond = MeshFunction(\"size_t\", mesh, 0)\n", - "tcond.set_all(0)\n", - "left.mark(tcond, 1)\n", - "\n", - "##################################\n", - "from vedo.dolfin import *\n", - "# embedWindow('itkwidgets') # backends are: itkwidgets, k3d or False\n", - "\n", - "plot(tcond, cmap='cool', shading='flat')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/stokes.ipynb b/examples/notebooks/dolfin/stokes.ipynb deleted file mode 100644 index ff3a53f3..00000000 --- a/examples/notebooks/dolfin/stokes.ipynb +++ /dev/null @@ -1,83 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\" This demo solves the Stokes equations, using quadratic elements for\n", - "the velocity and first degree elements for the pressure (Taylor-Hood elements).\"\"\"\n", - "# Credits: https://github.com/pf4d/fenics_scripts/blob/master/cbc_block/stokes.py\n", - "from dolfin import *\n", - "from time import time\n", - "from vedo.dolfin import datadir\n", - "\n", - "# Load mesh and subdomains\n", - "mesh = Mesh(datadir+\"dolfin_fine.xml\")\n", - "sub_domains = MeshFunction(\"size_t\", mesh, datadir+\"dolfin_fine_subdomains.xml.gz\")\n", - "\n", - "# Define function spaces\n", - "P2 = VectorElement(\"Lagrange\", mesh.ufl_cell(), 2)\n", - "P1 = FiniteElement(\"Lagrange\", mesh.ufl_cell(), 1)\n", - "TH = P2 * P1\n", - "W = FunctionSpace(mesh, TH)\n", - "\n", - "# No-slip boundary condition for velocity\n", - "noslip = Constant((0, 0))\n", - "bc0 = DirichletBC(W.sub(0), noslip, sub_domains, 0)\n", - "\n", - "# Inflow boundary condition for velocity\n", - "inflow = Expression((\"-sin(x[1]*pi)\", \"0.0\"), degree=2)\n", - "bc1 = DirichletBC(W.sub(0), inflow, sub_domains, 1)\n", - "bcs = [bc0, bc1]\n", - "\n", - "# Define variational problem\n", - "(u, p) = TrialFunctions(W)\n", - "(v, q) = TestFunctions(W)\n", - "f = Constant((0, 0))\n", - "a = (inner(grad(u), grad(v)) - div(v)*p + q*div(u))*dx\n", - "L = inner(f, v)*dx\n", - "w = Function(W)\n", - "\n", - "solve(a == L, w, bcs) #solver_parameters={'linear_solver':'mumps'}\n", - "(u, p) = w.split() # Split the mixed solution using a shallow copy\n", - "\n", - "######################################################## vedo:\n", - "from vedo.dolfin import plot, embedWindow\n", - "\n", - "# embedWindow('itkwidgets') # backends are: itkwidgets, k3d or False\n", - "\n", - "plot(u, mode='mesh and arrows', warpZfactor=-0.05, scale=0.02)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/dolfin/submesh_boundary.ipynb b/examples/notebooks/dolfin/submesh_boundary.ipynb deleted file mode 100644 index 113aa6c9..00000000 --- a/examples/notebooks/dolfin/submesh_boundary.ipynb +++ /dev/null @@ -1,71 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"Extract submesh boundaries.\"\"\"\n", - "#Credit: https://fenicsproject.discourse.group/t/output-parts-of-boundary/537\n", - "from fenics import *\n", - "from mshr import *\n", - "from numpy import array\n", - "from numpy.linalg import norm\n", - "\n", - "domain = Box(Point(0,0,0), Point(10,10,10)) - Sphere(Point(5,5,5), 3)\n", - "mesh = generate_mesh(domain, 32)\n", - "exterior = BoundaryMesh(mesh, \"exterior\")\n", - "\n", - "def inSphere(x):\n", - " v = x - array([5, 5, 5])\n", - " return norm(v) < 3 + 1e2 * DOLFIN_EPS\n", - "\n", - "class SphereDomain(SubDomain):\n", - " def inside(self, x, on_boundary):\n", - " return inSphere(x)\n", - "\n", - "class BoxDomain(SubDomain):\n", - " def inside(self, x, on_boundary):\n", - " return not inSphere(x)\n", - "\n", - "sph = SubMesh(exterior, SphereDomain())\n", - "box = SubMesh(exterior, BoxDomain())\n", - "\n", - "##################################\n", - "from vedo.dolfin import *\n", - "\n", - "plot(sph, c='r')\n", - "plot(box, c='y', wireframe=True, add=True, zoom=.7)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/pyplot/latex.ipynb b/examples/notebooks/pyplot/latex.ipynb deleted file mode 100644 index d54a7e67..00000000 --- a/examples/notebooks/pyplot/latex.ipynb +++ /dev/null @@ -1,62 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from vedo import *\n", - "embedWindow('2d')\n", - "\n", - "# https://matplotlib.org/tutorials/text/mathtext.html\n", - "vp = Plotter(bg='white', axes=1)\n", - "\n", - "latex1 = r'x= \\frac{ - b \\pm \\sqrt {b^2 - 4ac} }{2a}'\n", - "latex2 = r'\\mathcal{A}\\mathrm{sin}(2 \\omega t)'\n", - "latex3 = r'I(Y | X)=\\sum_{x \\in \\mathcal{X}, y \\in \\mathcal{Y}} p(x, y) \\log \\left(\\frac{p(x)}{p(x, y)}\\right)'\n", - "latex4 = r'\\Gamma_{\\epsilon}(x)=\\left[1-e^{-2 \\pi \\epsilon}\\right]^{1-x} \\prod_{n=0}^{\\infty} \\frac{1-\\exp (-2 \\pi \\epsilon(n+1))}{1-\\exp (-2 \\pi \\epsilon(x+n))}'\n", - "latex5 = r'\\left( \\begin{array}{l}{c t^{\\prime}} \\\\ {x^{\\prime}} \\\\ {y^{\\prime}} \\\\ {z^{\\prime}}\\end{array}\\right)=\\left( \\begin{array}{cccc}{\\gamma} & {-\\gamma \\beta} & {0} & {0} \\\\ {-\\gamma \\beta} & {\\gamma} & {0} & {0} \\\\ {0} & {0} & {1} & {0} \\\\ {0} & {0} & {0} & {1}\\end{array}\\right) \\left( \\begin{array}{l}{c t} \\\\ {x} \\\\ {y} \\\\ {z}\\end{array}\\right)'\n", - "latex6 = r'\\mathrm{CO}_{2}+6 \\mathrm{H}_{2} \\mathrm{O} \\rightarrow \\mathrm{C}_{6} \\mathrm{H}_{12} \\mathrm{O}_{6}+6 \\mathrm{O}_{2}'\n", - "latex7 = r'x \\mathrm{(arb. units)}'\n", - "\n", - "l = Latex(latex4, s=1, c='b', bg='', alpha=0.9, usetex=False)\n", - "l.crop(0.3, 0.3) # crop top and bottom 30%\n", - "l.pos(2,0,0)\n", - "\n", - "p = Point()\n", - "box = l.box() # return the bounding box of a mesh\n", - "\n", - "vp.show(p, l, box, zoom=1.2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.6" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/pyplot/plot2_errband.ipynb b/examples/notebooks/pyplot/plot2_errband.ipynb index 8a0ce7e2..8a30bddf 100644 --- a/examples/notebooks/pyplot/plot2_errband.ipynb +++ b/examples/notebooks/pyplot/plot2_errband.ipynb @@ -37,7 +37,7 @@ "plt += Rectangle([1,0.5], [2.7,5], alpha=0.2, c='k')\n", "\n", "# Add some text and latex formula\n", - "plt += Text(\"excluded\", s=0.2, c='k').rotateZ(20).pos(1.3, 3.7)\n", + "plt += Text3D(\"excluded\", s=0.2, c='k').rotateZ(20).pos(1.3, 3.7)\n", "plt += Latex(r\"y(t)=2+2\\cdot\\frac{\\sin(2t)}{(t+1)}\", pos=(4.7, 4.7), s=.8, c='db')\n", "\n", "# Add a star marker at maximum of function (at z=0.1, so it stays on top):\n", @@ -73,7 +73,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/examples/notebooks/pyplot/quiver.ipynb b/examples/notebooks/pyplot/quiver.ipynb deleted file mode 100644 index abeb8f57..00000000 --- a/examples/notebooks/pyplot/quiver.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"A simple quiver plot\"\"\"\n", - "from vedo import *\n", - "from vedo.pyplot import quiver\n", - "embedWindow('2d')\n", - "\n", - "vp = Plotter(axes=1, bg='white')\n", - "\n", - "# create points and associated displacements\n", - "pts1 = Grid(sx=1.0, sy=1.0).points()\n", - "pts2 = Grid(sx=1.2, sy=1.2).rotateZ(4).points()\n", - "\n", - "qp = quiver(pts1, # points\n", - " pts2-pts1, # associated vectors\n", - " cmap='jet', # can also be a fixed color\n", - " )\n", - "\n", - "vp.show(qp, zoom=1.2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/pyplot/scatter1.ipynb b/examples/notebooks/pyplot/scatter1.ipynb deleted file mode 100644 index f95fe1e0..00000000 --- a/examples/notebooks/pyplot/scatter1.ipynb +++ /dev/null @@ -1,58 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"A simple scatter plot with plotxy()\"\"\"\n", - "from vedo import *\n", - "from vedo.pyplot import plot\n", - "from numpy.random import randn\n", - "embedWindow('2d')\n", - "\n", - "x = randn(100)\n", - "y = randn(100)*20\n", - "\n", - "plt = plot( x, y, # accepts different formats\n", - " xtitle=\"variable x\",\n", - " ytitle=\"variable y\",\n", - " line=False,\n", - " marker=\".\", # marker style\n", - " mc=\"dr\", # marker color\n", - ")\n", - "\n", - "show(plt, axes=1, zoom=1.4)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/pyplot/scatter2.ipynb b/examples/notebooks/pyplot/scatter2.ipynb deleted file mode 100644 index e5666d20..00000000 --- a/examples/notebooks/pyplot/scatter2.ipynb +++ /dev/null @@ -1,68 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Scatter plot of a gaussian distribution\n", - "# with varying color and point sizes\n", - "import numpy as np\n", - "from vedo import *\n", - "from vedo.pyplot import plot\n", - "embedWindow('2d')\n", - "\n", - "n = 1000\n", - "x = np.random.randn(n)\n", - "y = np.random.randn(n)\n", - "\n", - "# define what size must have each marker:\n", - "marker_sizes = np.sin(2*x)/8\n", - "\n", - "# define a (r,g,b) list of colors for each marker:\n", - "marker_cols = np.c_[np.cos(2*x), np.zeros(n), np.zeros(n)]\n", - "\n", - "plt = plot(x, y,\n", - " ma=0.3,\n", - " marker=\">\", # marker style\n", - " ms=marker_sizes, # VARIABLE marker sizes\n", - " mc=marker_cols, # VARIABLE marker colors\n", - " line=False,\n", - " xtitle=\"variable A\",\n", - " ytitle=\"variable B\",\n", - " )\n", - "\n", - "show(plt, zoom=1.2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/pyplot/scatter3.ipynb b/examples/notebooks/pyplot/scatter3.ipynb deleted file mode 100644 index 159728f9..00000000 --- a/examples/notebooks/pyplot/scatter3.ipynb +++ /dev/null @@ -1,72 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"Create a scatter plot to overlay three different distributions\"\"\"\n", - "from numpy.random import randn\n", - "from vedo.pyplot import plot\n", - "from vedo import *\n", - "embedWindow('2d')\n", - "\n", - "### first scatter plot in blue\n", - "x = randn(4000) * 3\n", - "y = randn(4000) * 2\n", - "# scatter cloud, place it at z=0:\n", - "pts1 = Points([x,y], c=\"blue\", alpha=0.5).z(0.0)\n", - "\n", - "\n", - "### second scatter plot in red\n", - "x = randn(4000) + 4\n", - "y = randn(4000) + 2\n", - "pts2 = Points([x,y], c=\"red\", alpha=0.5).z(0.1)\n", - "\n", - "\n", - "### third scatter plot with marker in black\n", - "x = randn(20) + 4\n", - "y = randn(20) - 4\n", - "mark = Marker('*', s=0.2, filled=True)\n", - "pts3 = Glyph([x,y], mark, c='k').z(0.2)\n", - "\n", - "\n", - "label = Text(\"preliminary\\nresults!\",\n", - " s=0.6, pos=(-8,3,.2), depth=0)\n", - "label.c('green').rotateZ(20)\n", - "\n", - "vp = Plotter(axes=1, bg=\"white\")\n", - "show(pts1, pts2, pts3, label, zoom=1.4)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/trimesh/first_example.ipynb b/examples/notebooks/trimesh/first_example.ipynb deleted file mode 100644 index c11e1d99..00000000 --- a/examples/notebooks/trimesh/first_example.ipynb +++ /dev/null @@ -1,72 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "Trimesh support and interoperability module.\n", - "\n", - "Install trimesh with:\n", - "> sudo apt install python3-rtree\n", - "> pip install rtree shapely\n", - "> conda install trimesh\n", - "\n", - "Check the example gallery at:\n", - " \n", - "https://github.com/marcomusy/vedo/tree/master/examples/other/trimesh\n", - "\"\"\"\n", - "import trimesh\n", - "import vedo\n", - "from vedo import trimesh2vtk, vtk2trimesh\n", - "\n", - "# uncomment this to pop a vtk rendering window instead of the K3D notebook backend\n", - "vedo.embedWindow(False)\n", - "\n", - "url = 'https://raw.githubusercontent.com/mikedh/trimesh/master/models/'\n", - "filename = vedo.download(url + 'machinist.XAML')\n", - "\n", - "mesh = trimesh.load(filename)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "actor = trimesh2vtk(mesh) # returns a Actor(vtkActor) object from Trimesh\n", - "vedo.show(mesh) # vedo visualizer (conversion is on the fly)\n", - "\n", - "trimsh_reconverted = vtk2trimesh(actor)\n", - "trimsh_reconverted.show() # this is the trimesh built-in visualizer\n", - "\n", - "# This closes the vtk rendering window. Use only if embedWindow(False)\n", - "vedo.closePlotter()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/trimesh/ray.ipynb b/examples/notebooks/trimesh/ray.ipynb deleted file mode 100644 index b24d9f6b..00000000 --- a/examples/notebooks/trimesh/ray.ipynb +++ /dev/null @@ -1,68 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import trimesh\n", - "import numpy as np\n", - "\n", - "# test on a sphere mesh\n", - "mesh = trimesh.creation.icosphere()\n", - "\n", - "# create some rays\n", - "ray_origins = np.array([[0, 0, -3], [1, 2, -3]])\n", - "ray_directions = np.array([[0, 0, 1], [0, -1, 1]])\n", - "\n", - "# run the mesh-ray query\n", - "locations, index_ray, index_tri = mesh.ray.intersects_location(\n", - " ray_origins=ray_origins, ray_directions=ray_directions\n", - ")\n", - "locs = trimesh.points.PointCloud(locations)\n", - "\n", - "# stack rays into line segments for visualization as Path3D\n", - "ray_visualize = trimesh.load_path(\n", - " np.hstack((ray_origins, ray_origins + ray_directions)).reshape(-1, 2, 3)\n", - ")\n", - "\n", - "print(\"The rays hit the mesh at coordinates:\\n\", locations)\n", - "print(\"The rays with index: {} hit triangles stored at mesh.faces[{}]\".format(index_ray, index_tri))\n", - "\n", - "# stack rays into line segments for visualization as Path3D\n", - "ray_visualize = trimesh.load_path(\n", - " np.hstack((ray_origins, ray_origins + ray_directions * 5.0)).reshape(-1, 2, 3)\n", - ")\n", - "\n", - "# make mesh white-ish\n", - "mesh.visual.face_colors = [200, 200, 250, 100]\n", - "mesh.visual.face_colors[index_tri] = [255, 0, 0, 255]\n", - "\n", - "from vedo import show\n", - "show(mesh, ray_visualize, locs)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/trimesh/section.ipynb b/examples/notebooks/trimesh/section.ipynb deleted file mode 100644 index 30c4caf5..00000000 --- a/examples/notebooks/trimesh/section.ipynb +++ /dev/null @@ -1,79 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import trimesh\n", - "import numpy as np\n", - "from vedo import show, Plane, printc, download\n", - "\n", - "# load the mesh from filename, file objects are also supported\n", - "f = download('https://github.com/mikedh/trimesh/raw/master/models/featuretype.STL')\n", - "mesh = trimesh.load_mesh(f)\n", - "\n", - "# get a single cross section of the mesh\n", - "mslice = mesh.section(plane_origin=mesh.centroid, plane_normal=[0,0,1])\n", - "\n", - "pl = Plane(mesh.centroid, normal=[0,0,1], sx=6, sy=4, alpha=0.3)\n", - "\n", - "slice_2D, to_3D = mslice.to_planar()\n", - "\n", - "# show objects\n", - "show(mesh, pl)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# if we wanted to take a bunch of parallel slices, like for a 3D printer\n", - "# we can do that easily with the section_multiplane method\n", - "# we're going to slice the mesh into evenly spaced chunks along z\n", - "# this takes the (2,3) bounding box and slices it into [minz, maxz]\n", - "z_extents = mesh.bounds[:,2]\n", - "# slice every .125 model units (eg, inches)\n", - "z_levels = np.arange(*z_extents, step=0.125)\n", - "\n", - "# find a bunch of parallel cross sections\n", - "sections = mesh.section_multiplane(plane_origin=mesh.bounds[0], \n", - " plane_normal=[0,0,1], \n", - " heights=z_levels)\n", - "N = len(sections)\n", - "printc(\"nr. of sections:\", N, c='green')\n", - "\n", - "# summing the array of Path2D objects will put all of the curves\n", - "# into one Path2D object, which we can plot easily\n", - "combined = np.sum(sections)\n", - "\n", - "# show objects in N synced renderers:\n", - "show(combined)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/notebooks/trimesh/shortest.ipynb b/examples/notebooks/trimesh/shortest.ipynb deleted file mode 100644 index a349f1e5..00000000 --- a/examples/notebooks/trimesh/shortest.ipynb +++ /dev/null @@ -1,75 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import trimesh\n", - "import networkx as nx\n", - "\n", - "# test on a sphere mesh\n", - "mesh = trimesh.primitives.Sphere()\n", - "\n", - "# edges without duplication\n", - "edges = mesh.edges_unique\n", - "\n", - "# the actual length of each unique edge\n", - "length = mesh.edges_unique_length\n", - "\n", - "# create the graph with edge attributes for length\n", - "g = nx.Graph()\n", - "for edge, L in zip(edges, length):\n", - " g.add_edge(*edge, length=L)\n", - "\n", - "# alternative method for weighted graph creation\n", - "# you can also create the graph with from_edgelist and\n", - "# a list comprehension, which is like 1.5x faster\n", - "ga = nx.from_edgelist([(e[0], e[1], {\"length\": L}) for e, L in zip(edges, length)])\n", - "\n", - "# arbitrary indices of mesh.vertices to test with\n", - "start, end = 0, int(len(mesh.vertices) / 2.0)\n", - "\n", - "# run the shortest path query using length for edge weight\n", - "path = nx.shortest_path(g, source=start, target=end, weight=\"length\")\n", - "\n", - "# VISUALIZE RESULT\n", - "# make the sphere transparent-ish\n", - "mesh.visual.face_colors = [100, 100, 100, 100]\n", - "\n", - "# Path3D with the path between the points\n", - "path_visual = trimesh.load_path(mesh.vertices[path])\n", - "\n", - "# visualizable two points\n", - "points_visual = trimesh.points.PointCloud(mesh.vertices[[start, end]])\n", - "\n", - "\n", - "from vedo import show\n", - "\n", - "show(mesh, points_visual, path_visual)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/other/non_blocking.py b/examples/other/non_blocking.py deleted file mode 100644 index da7684f9..00000000 --- a/examples/other/non_blocking.py +++ /dev/null @@ -1,24 +0,0 @@ -"""Non blocking interactive rendering window, -python flow is not blocked -but displayed objects cannot be accessed""" -import time, os -from multiprocessing import Process -from vedo import Sphere, show, printc - - -printc("..starting main", c='g') - -sphere = Sphere().alpha(0.1).lw(0.1) - -# ------ instead of (typical): -#show(sphere, __doc__, axes=1) - -# ------ spawn an independent subprocess: -def spawn(): show(sphere, __doc__, axes=1) -Process(target=spawn).start() - -printc("..python flow is not blocked, wait 1 sec..", c='y') -time.sleep(1) - -printc("..continuing in main", c='r') -os._exit(0) # this exits immediately with no cleanup or buffer flushing diff --git a/examples/volumetric/slicePlane1.py b/examples/volumetric/slicePlane1.py index 718a08d4..4a87ba24 100644 --- a/examples/volumetric/slicePlane1.py +++ b/examples/volumetric/slicePlane1.py @@ -9,17 +9,15 @@ arr = sl.getPointArray() def func(evt): - if not evt.actor: return - - ptid= evt.actor.closestPoint(evt.picked3d, returnPointId=True) - txt = f"Probing:\n{precision(evt.actor.picked3d, 3)}\nvalue = {arr[ptid]}" - sph = Sphere(evt.actor.points(ptid), c='orange7').pickable(False) - vig = sph.vignette(txt, s=7, offset=(-150,15), font=2)#.followCamera() - msg = Text2D(txt, pos='bottom-left', font="VictorMono") - plt.remove(plt.actors[-3:]) # remove the last 3 - plt.add([sph, vig, msg]) # add the new 3 ones + if not evt.actor: + return + pid = evt.actor.closestPoint(evt.picked3d, returnPointId=True) + txt = f"Probing:\n{precision(evt.actor.picked3d, 3)}\nvalue = {arr[pid]}" + sph = Sphere(evt.actor.points(pid), c='orange7').pickable(False) + vig = sph.vignette(txt, s=7, offset=(-150,15), font=2).followCamera() + plt.remove(plt.actors[-2:]).add([sph, vig]) #remove old 2 & add the new 2 plt = show(vol, sl, __doc__, axes=9, bg='k', bg2='bb', interactive=False) -plt.actors += [None, None, None] # holds [sphere, vignette, text2d] -plt.addCallback('MouseMove', func) +plt.actors += [None, None] # 2 placeholders for [sphere, vignette] +plt.addCallback('as my mouse moves please call', func) # be kind to vedo interactive() diff --git a/requirements.txt b/requirements.txt index 6613519c..5ed5fb38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -vtk +vtk==8.1.2,>=7 diff --git a/vedo/addons.py b/vedo/addons.py index 10b5c268..492bb192 100644 --- a/vedo/addons.py +++ b/vedo/addons.py @@ -1322,6 +1322,9 @@ def buildRulerAxes( dx,dy,dz = (y1-y0)*xpad, (x1-x0)*ypad, (y1-y0)*zpad d = np.sqrt((y1-y0)**2+(x1-x0)**2+(z1-z0)**2) + if not d: + return None + if s is None: s = d/75 @@ -1358,7 +1361,10 @@ def buildRulerAxes( cxy = shapes.Circle([x0,y1,z0], r=d, res=15) acts.extend([lx,ly,cxy]) - macts = merge(acts).c(c).alpha(alpha).bc('t') + macts = merge(acts) + if not macts: + return None + macts.c(c).alpha(alpha).bc('t') macts.UseBoundsOff() return macts @@ -2580,10 +2586,12 @@ def addGlobalAxes(axtype=None, c=None): xtitle=plt.xtitle+' - ', ytitle=plt.ytitle+' - ', ztitle=plt.ztitle+' - ') + plt.axes_instances[r] = rulax + if not rulax: + return None rulax.UseBoundsOff() rulax.PickableOff() plt.renderer.AddActor(rulax) - plt.axes_instances[r] = rulax elif plt.axes == 8: vbb = computeVisibleBounds()[0] diff --git a/vedo/backends.py b/vedo/backends.py index 9b52363e..a3404122 100644 --- a/vedo/backends.py +++ b/vedo/backends.py @@ -8,7 +8,7 @@ from vedo.volume import Volume import vedo.settings as settings -import vedo.addons as addons +# import vedo.addons as addons import vedo.shapes as shapes import vedo.utils as utils from vtk.util.numpy_support import vtk_to_numpy @@ -53,17 +53,18 @@ def getNotebookBackend(actors2show, zoom, viewup): else: actors2show2.append(ia) - vbb, sizes, min_bns, max_bns = addons.computeVisibleBounds() - kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5] + # vbb, sizes, _, _ = addons.computeVisibleBounds() + # kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5] settings.notebook_plotter = k3d.plot(axes=[vp.xtitle, vp.ytitle, vp.ztitle], menu_visibility=True, - height=int(vp.size[1]/2) ) - settings.notebook_plotter.grid = kgrid + # height=int(vp.size[1]/2), + ) + # settings.notebook_plotter.grid = kgrid settings.notebook_plotter.lighting = 1.2 # set k3d camera - settings.notebook_plotter.camera_auto_fit = False + settings.notebook_plotter.camera_auto_fit = True if settings.plotter_instance and settings.plotter_instance.camera: k3dc = utils.vtkCameraToK3D(settings.plotter_instance.camera) @@ -72,24 +73,24 @@ def getNotebookBackend(actors2show, zoom, viewup): k3dc[1] /= zoom k3dc[2] /= zoom settings.notebook_plotter.camera = k3dc - else: - vsx, vsy, vsz = vbb[0]-vbb[1], vbb[2]-vbb[3], vbb[4]-vbb[5] - vss = numpy.linalg.norm([vsx, vsy, vsz]) - if zoom: - vss /= zoom - vfp = (vbb[0]+vbb[1])/2, (vbb[2]+vbb[3])/2, (vbb[4]+vbb[5])/2 # camera target - if viewup == 'z': - vup = (0,0,1) # camera up vector - vpos= vfp[0] + vss/1.9, vfp[1] + vss/1.9, vfp[2]+vss*0.01 # camera position - elif viewup == 'x': - vup = (1,0,0) - vpos= vfp[0]+vss*0.01, vfp[1] + vss/1.5, vfp[2] # camera position - else: - vup = (0,1,0) - vpos= vfp[0]+vss*0.01, vfp[1]+vss*0.01, vfp[2] + vss/1.5 # camera position - settings.notebook_plotter.camera = [vpos[0], vpos[1], vpos[2], - vfp[0], vfp[1], vfp[2], - vup[0], vup[1], vup[2] ] + # else: + # vsx, vsy, vsz = vbb[0]-vbb[1], vbb[2]-vbb[3], vbb[4]-vbb[5] + # vss = numpy.linalg.norm([vsx, vsy, vsz]) + # if zoom: + # vss /= zoom + # vfp = (vbb[0]+vbb[1])/2, (vbb[2]+vbb[3])/2, (vbb[4]+vbb[5])/2 # camera target + # if viewup == 'z': + # vup = (0,0,1) # camera up vector + # vpos= vfp[0] + vss/1.9, vfp[1] + vss/1.9, vfp[2]+vss*0.01 # camera position + # elif viewup == 'x': + # vup = (1,0,0) + # vpos= vfp[0]+vss*0.01, vfp[1] + vss/1.5, vfp[2] # camera position + # else: + # vup = (0,1,0) + # vpos= vfp[0]+vss*0.01, vfp[1]+vss*0.01, vfp[2] + vss/1.5 # camera position + # settings.notebook_plotter.camera = [vpos[0], vpos[1], vpos[2], + # vfp[0], vfp[1], vfp[2], + # vup[0], vup[1], vup[2] ] if not vp.axes: settings.notebook_plotter.grid_visible = False @@ -187,7 +188,7 @@ def getNotebookBackend(actors2show, zoom, viewup): # print('Mesh', ia.name, ia.N(), len(ia.faces())) kobj = k3d.vtk_poly_data(iapoly, name=name, - color=_rgb2int(iap.GetColor()), + # color=_rgb2int(iap.GetColor()), color_attribute=color_attribute, color_map=kcmap, opacity=iap.GetOpacity(), @@ -205,16 +206,15 @@ def getNotebookBackend(actors2show, zoom, viewup): scals = vtk_to_numpy(vtkscals) kcols = k3d.helpers.map_colors(scals, kcmap, [scals_min,scals_max]).astype(numpy.uint32) - sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) + # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) kobj = k3d.points(ia.points().astype(numpy.float32), color=_rgb2int(iap.GetColor()), colors=kcols, opacity=iap.GetOpacity(), - shader="3d", - point_size=iap.GetPointSize()*sqsize/800, + shader="dot", + point_size=3, # point_size=iap.GetPointSize()*sqsize/800, name=name, - #compression_level=9, ) settings.notebook_plotter += kobj @@ -231,7 +231,7 @@ def getNotebookBackend(actors2show, zoom, viewup): # kcols = k3d.helpers.map_colors(scals, kcmap, # [scals_min,scals_max]).astype(numpy.uint32) - sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) + # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) for i, ln_idx in enumerate(ia.lines()): if i>200: @@ -243,7 +243,7 @@ def getNotebookBackend(actors2show, zoom, viewup): # colors=kcols, opacity=iap.GetOpacity(), shader="thick", - width=iap.GetLineWidth()*sqsize/1000, + # width=iap.GetLineWidth()*sqsize/1000, name=name, ) diff --git a/vedo/base.py b/vedo/base.py index 0d9b699a..81479cbe 100644 --- a/vedo/base.py +++ b/vedo/base.py @@ -48,7 +48,7 @@ def __init__(self): self._time = 0 self.renderedAt = set() self.transform = None - self._set2actcam = False + self._set2actcam = False # used by mesh.followCamera() def address(self): """ diff --git a/vedo/docs.py b/vedo/docs.py index 43cc03e9..b07950e8 100644 --- a/vedo/docs.py +++ b/vedo/docs.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function import vtk, sys __all__ = [] @@ -32,8 +31,7 @@ def tips(): msg += "| S save a screenshot |\n" msg += "| E export rendering window to numpy file |\n" msg += "| q return control to python script |\n" - msg += "| Esc close the rendering window and continue |\n" - msg += "| F1 abort execution and exit python kernel |\n" + msg += "| Esc abort execution and exit python kernel |\n" msg += "|----------------------------------------------------------|\n" msg += "| Mouse: Left-click rotate scene / pick actors |\n" msg += "| Middle-click pan scene |\n" diff --git a/vedo/dolfin.py b/vedo/dolfin.py index 5a9b668f..c2878a31 100644 --- a/vedo/dolfin.py +++ b/vedo/dolfin.py @@ -11,7 +11,7 @@ from vedo.colors import printc import vedo.settings as settings -from vedo.settings import datadir, embedWindow +from vedo.settings import datadir, dataurl, embedWindow from vedo.mesh import Mesh @@ -39,9 +39,9 @@ .. code-block:: python import dolfin - from vedo.dolfin import datadir, plot + from vedo.dolfin import dataurl, plot - mesh = dolfin.Mesh(datadir+"dolfin_fine.xml") + mesh = dolfin.Mesh(dataurl+"dolfin_fine.xml") plot(mesh) @@ -116,6 +116,7 @@ "Text2D", "Latex", "datadir", + "dataurl", "screenshot", "Video", "exportWindow", diff --git a/vedo/io.py b/vedo/io.py index 3bcc7132..9fee746c 100644 --- a/vedo/io.py +++ b/vedo/io.py @@ -5,13 +5,12 @@ import numpy as np import time +import vedo import vedo.utils as utils import vedo.colors as colors from vedo.assembly import Assembly from vedo.mesh import Mesh from vedo.pointcloud import Points -from vedo.ugrid import UGrid -from vedo.tetmesh import TetMesh from vedo.picture import Picture from vedo.volume import Volume import vedo.docs as docs @@ -232,7 +231,7 @@ def _load_file(filename, unpack): elif isinstance(b, vtk.vtkImageData): acts.append(Volume(b)) elif isinstance(b, vtk.vtkUnstructuredGrid): - acts.append(UGrid(b)) + acts.append(vedo.UGrid(b)) return acts else: return mb @@ -310,7 +309,7 @@ def _load_file(filename, unpack): return None if isinstance(routput, vtk.vtkUnstructuredGrid): - actor = TetMesh(routput) + actor = vedo.TetMesh(routput) else: actor = Mesh(routput) @@ -875,28 +874,23 @@ def _fillmesh(obj, adict): elif isinstance(obj, Picture): adict['type'] = 'Picture' _fillcommon(obj, adict) - arr = vtk_to_numpy(obj.inputdata().GetPointData().GetScalars()) - adict['array'] = arr + adict['array'] = vtk_to_numpy(obj.inputdata().GetPointData().GetScalars()) adict['shape'] = obj.inputdata().GetDimensions() + print('toNumpy(): vedo.Picture', obj.shape, obj.GetPosition()) - ######################################################## Annotation - elif isinstance(obj, vtk.vtkCornerAnnotation): - tx = '' - for i in range(8): - tx = obj.GetText(i) - if tx: break - if tx: - adict['type'] = 'Annotation' - #adict['rendered_at'] = obj.renderedAt - adict['text'] = obj.GetText(i) - adict['position'] = i - adict['color'] = obj.GetTextProperty().GetColor() - adict['font'] = obj.GetTextProperty().GetFontFamilyAsString() - if 'File' in adict['font']: - adict['font'] = os.path.basename(obj.GetTextProperty().GetFontFile()).split('.')[0] - adict['size'] = obj.GetNonlinearFontScaleFactor() - adict['bgcol'] = obj.GetTextProperty().GetBackgroundColor() - adict['alpha'] = obj.GetTextProperty().GetBackgroundOpacity() + ######################################################## Text2D + elif isinstance(obj, vedo.Text2D): + adict['type'] = 'Text2D' + adict['rendered_at'] = obj.renderedAt + adict['text'] = obj.text() + adict['position'] = obj.GetPosition() + adict['color'] = obj.property.GetColor() + adict['font'] = obj.font() + adict['size'] = obj.property.GetFontSize()/22.5 + adict['bgcol'] = obj.property.GetBackgroundColor() + adict['alpha'] = obj.property.GetBackgroundOpacity() + adict['frame'] = obj.property.GetFrame() + # print('toNumpy(): vedo.Text2D', obj.text()[:10], obj.font(), obj.GetPosition()) else: pass @@ -1075,16 +1069,25 @@ def _buildmesh(d): _loadcommon(vimg, d) objs.append(vimg) - ### Annotation + ### Text2D + elif 'text2d' == d['type'].lower(): + t = vedo.shapes.Text2D(d['text'], font=d['font'], c=d['color']) + t.pos(d['position']).size(d['size']) + t.background(d['bgcol'], d['alpha']) + if d['frame']: + t.frame(d['bgcol']) + objs.append(t) + + ### Annotation ## backward compatibility - will disappear elif 'annotation' == d['type'].lower(): from vedo.shapes import Text2D pos = d['position'] - if isinstance(pos, int): ## backward compatibility - pos = "top-left" ## backward compatibility - d['size'] *= 2.7 ## old convention ## backward compatibility + if isinstance(pos, int): + pos = "top-left" + d['size'] *= 2.7 t = Text2D(d['text'], font=d['font'], c=d['color']).pos(pos) t.background(d['bgcol'], d['alpha']).size(d['size']).frame(d['bgcol']) - objs.append(t) + objs.append(t) ## backward compatibility if len(objs) == 1: return objs[0] @@ -1421,20 +1424,15 @@ def exportWindow(fileoutput, binary=False): sdict['defaultFont'] = settings.defaultFont sdict['objects'] = [] - allobjs = vp.getMeshes() + vp.getVolumes() + allobjs = vp.getMeshes(includeNonPickables=True) + vp.getVolumes(includeNonPickables=True) acts2d = vp.renderer.GetActors2D() acts2d.InitTraversal() for i in range(acts2d.GetNumberOfItems()): a = acts2d.GetNextItem() - if isinstance(a, vtk.vtkCornerAnnotation): + if isinstance(a, vedo.Text2D): allobjs.append(a) - # ir = vp.renderers.index(vp.renderer) - # for a in vp.actors: - # # because of vtkXYPlotActor is not wrapped - # if hasattr(a, 'renderedAt') and ir in a.renderedAt: - # allobjs.append(a) - # allobjs = list(set(allobjs)) # unique + allobjs = list(set(allobjs)) # make sure its unique for a in allobjs: sdict['objects'].append(toNumpy(a)) diff --git a/vedo/mesh.py b/vedo/mesh.py index a5201864..a0129993 100644 --- a/vedo/mesh.py +++ b/vedo/mesh.py @@ -83,6 +83,7 @@ def __init__( ): Points.__init__(self) + self.line_locator = None self._current_texture_name = '' # used by plotter._keypress self._mapper.SetInterpolateScalarsBeforeMapping(vedo.settings.interpolateScalarsBeforeMapping) @@ -94,6 +95,7 @@ def __init__( inputtype = str(type(inputobj)) + if inputobj is None: pass @@ -158,19 +160,6 @@ def __init__( print("Could not add meshio cell data, skip.") elif "meshlab" in inputtype: - # if "MeshSet" in inputtype: - # inputobj = inputobj.current_mesh() - # mpoints, mcells = inputobj.vertex_matrix(), inputobj.face_matrix() - # pnorms = inputobj.vertex_normal_matrix() - # cnorms = inputobj.face_normal_matrix() - # if len(mcells): - # self._polydata = buildPolyData(mpoints, mcells) - # else: - # self._polydata = buildPolyData(mpoints, None) - # if len(pnorms): - # self._polydata.GetPointData().SetNormals(numpy_to_vtk(pnorms, deep=True)) - # if len(cnorms): - # self._polydata.GetCellData().SetNormals(numpy_to_vtk(cnorms, deep=True)) self._polydata = vedo.utils.meshlab2vedo(inputobj) elif isSequence(inputobj): @@ -221,16 +210,16 @@ def __init__( self._mapper.SetInputData(self._polydata) - self.line_locator = None - self._bfprop = None # backface property holder prp = self.GetProperty() prp.SetInterpolationToPhong() if vedo.settings.renderLinesAsTubes: - if hasattr(prp, 'RenderLinesAsTubesOn'): + try: prp.RenderLinesAsTubesOn() + except: + pass # set the color by c or by scalar if self._polydata: diff --git a/vedo/picture.py b/vedo/picture.py index a0901451..effda3c0 100644 --- a/vedo/picture.py +++ b/vedo/picture.py @@ -105,6 +105,20 @@ def _update(self, data): self._mapper.Modified() return self + def clone(self, transform=False): + """Return an exact copy of the input Picture. + If transform is True, it is given the same scaling and position.""" + img = vtk.vtkImageData() + img.DeepCopy(self._data) + pic = Picture(img) + if transform: + # assign the same transformation to the copy + pic.SetOrigin(self.GetOrigin()) + pic.SetScale(self.GetScale()) + pic.SetOrientation(self.GetOrientation()) + pic.SetPosition(self.GetPosition()) + return pic + def text(self, txt, pos=(0,0,0), s=1, diff --git a/vedo/plotter.py b/vedo/plotter.py index 866a10de..ac4cb063 100644 --- a/vedo/plotter.py +++ b/vedo/plotter.py @@ -462,7 +462,6 @@ def __init__( self._extralight = None self.size = size self.interactor = None - # self.allowInteraction = None self.keyheld = '' self.xtitle = settings.xtitle # x axis label and units self.ytitle = settings.ytitle # y axis label and units @@ -480,21 +479,22 @@ def __init__( ############################################################ notebookBackend = settings.notebookBackend - if notebookBackend and notebookBackend.lower() == '2d': - self.offscreen = True - if self.size == "auto": - self.size = (900, 700) + if notebookBackend: + if notebookBackend == '2d': + self.offscreen = True + if self.size == "auto": + self.size = (900, 700) - if notebookBackend and notebookBackend not in ["panel","2d","ipyvtk"]: - self.interactive = False - self.interactor = None - self.window = None - self.camera = None # let the backend choose - if self.size == "auto": - self.size = (1000, 1000) - ############################ - return ##################### - ############################ + elif notebookBackend == "k3d": + self.interactive = False + self.interactor = None + self.window = None + self.camera = None # let the backend choose + if self.size == "auto": + self.size = (1000, 1000) + ############################ + return ##################### + ############################ # more settings if settings.useDepthPeeling: @@ -900,7 +900,7 @@ def backgroundColor(self, c1=None, c2=None, at=None): #################################################### def load(self, filename, unpack=True, force=False): """ - Load Mesh and Volume objects from file. + Load objects from file. The output will depend on the file extension. See examples below. :param bool unpack: only for multiblock data, @@ -935,107 +935,60 @@ def load(self, filename, unpack=True, force=False): return acts - def getVolumes(self, obj=None, renderer=None): + def getMeshes(self, at=None, includeNonPickables=False): """ - Return the list of the rendered Volumes. + Return a list of Meshes from the specified renderer. - If ``obj`` is: - ``None``, return volumes of current renderer - - ``int``, return volumes in given renderer number - - :param int,vtkRenderer renderer: specify which renederer to look into. + :param int at: specify which renderer to look into. + :param bool includeNonPickables: include non-pickable objects """ - if renderer is None: + if at is None: renderer = self.renderer - elif isinstance(renderer, int): - renderer = self.renderers.index(renderer) - else: - return [] - - if obj is None or isinstance(obj, int): - if obj is None: - acs = renderer.GetVolumes() - elif obj >= len(self.renderers): - printc("Error in getVolumes(): non existing renderer", obj, c='r') - return [] - else: - acs = self.renderers[obj].GetVolumes() - vols = [] - acs.InitTraversal() - for i in range(acs.GetNumberOfItems()): - a = acs.GetNextItem() - if a.GetPickable(): - r = self.renderers.index(renderer) - if a == self.axes_instances[r]: - continue - vols.append(a) - return vols - - def getMeshes(self, obj=None, renderer=None): - """ - Return a list of Meshes (which may include Volume objects too). - - If ``obj`` is: - ``None``, return meshes of current renderer - - ``int``, return meshes in given renderer number - - ``vtkAssembly`` return the contained meshes + at=0 + elif isinstance(at, int): + renderer = self.renderers[at] + + has_global_axes = False + if isinstance(self.axes_instances[at], vedo.Assembly): + has_global_axes=True + + actors = [] + acs = renderer.GetActors() + acs.InitTraversal() + for i in range(acs.GetNumberOfItems()): + a = acs.GetNextItem() + if isinstance(a, vtk.vtkVolume): + continue + if includeNonPickables or a.GetPickable(): + if a == self.axes_instances[at]: + continue + if has_global_axes and a in self.axes_instances[at].actors: + continue + actors.append(a) + return actors - ``string``, return meshes matching legend name + def getVolumes(self, at=None, includeNonPickables=False): + """ + Return a list of Volumes from the specified renderer. - :param int,vtkRenderer renderer: specify which renederer to look into. + :param int at: specify which renderer to look into. + :param bool includeNonPickables: include non-pickable objects """ - if renderer is None: + if at is None: renderer = self.renderer - elif isinstance(renderer, int): - renderer = self.renderers.index(renderer) - else: - return [] - - if obj is None or isinstance(obj, int): - if obj is None: - acs = renderer.GetActors() - elif obj >= len(self.renderers): - printc("Error in getMeshes(): non existing renderer", obj, c='r') - return [] - else: - acs = self.renderers[obj].GetActors() - - actors = [] - acs.InitTraversal() - for i in range(acs.GetNumberOfItems()): - a = acs.GetNextItem() - if a.GetPickable(): - r = self.renderers.index(renderer) - if a == self.axes_instances[r]: - continue - actors.append(a) - return actors - - elif isinstance(obj, vtk.vtkAssembly): - cl = vtk.vtkPropCollection() - obj.GetActors(cl) - actors = [] - cl.InitTraversal() - for i in range(obj.GetNumberOfPaths()): - act = vtk.vtkActor.SafeDownCast(cl.GetNextProp()) - if act.GetPickable(): - actors.append(act) - return actors - - elif isinstance(obj, str): # search the actor by the legend name - actors = [] - for a in self.actors: - if hasattr(a, "name") and obj in a.name: - actors.append(a) - return actors - - elif isinstance(obj, vtk.vtkActor): - return [obj] - - return [] + at=0 + elif isinstance(at, int): + renderer = self.renderers[at] + + vols = [] + acs = renderer.GetVolumes() + acs.InitTraversal() + for i in range(acs.GetNumberOfItems()): + a = acs.GetNextItem() + if includeNonPickables or a.GetPickable(): + vols.append(a) + return vols + def resetCamera(self): """Reset the camera position and zooming.""" @@ -1948,7 +1901,7 @@ def show(self, *actors, **options): self.renderer.AddActor(ia) if hasattr(ia, '_set2actcam') and ia._set2actcam: - ia.SetCamera(self.camera) + ia.SetCamera(self.camera) # used by mesh.followCamera() if hasattr(ia, 'renderedAt'): ia.renderedAt.add(at) @@ -1967,15 +1920,6 @@ def show(self, *actors, **options): if ia.scalarbar not in self.scalarbars: self.scalarbars.append(ia.scalarbar) - # if hasattr(ia, 'GetTextProperty'): - # #fix gray color of corner annotations - # cacol = np.array(ia.GetTextProperty().GetColor()) - # if np.linalg.norm(cacol-(.5,.5,.5))/3 < 0.05: - # c = (0.9, 0.9, 0.9) - # if np.sum(self.renderer.GetBackground()) > 1.5: - # c = (0.1, 0.1, 0.1) - # ia.GetTextProperty().SetColor(c) - if hasattr(ia, 'flagText') and self.interactor and not self.offscreen: #check balloons if ia.flagText: @@ -2010,7 +1954,7 @@ def show(self, *actors, **options): self.flagWidget.RemoveBalloon(ia) # remove the ones that are not in actors2show (and their scalarbar if any) - for ia in self.getMeshes(at) + self.getVolumes(at): + for ia in self.getMeshes(at, includeNonPickables=True) + self.getVolumes(at, includeNonPickables=True): if ia not in actors2show: self.renderer.RemoveActor(ia) if hasattr(ia, 'scalarbar') and ia.scalarbar: @@ -2719,7 +2663,10 @@ def _keypress(self, iren, event): if hasattr(self.axes_instances[clickedr], "EnabledOff"): # widget self.axes_instances[clickedr].EnabledOff() else: - self.renderer.RemoveActor(self.axes_instances[clickedr]) + try: + self.renderer.RemoveActor(self.axes_instances[clickedr]) + except: + pass self.axes_instances[clickedr] = None if not self.axes: self.axes=0 if isinstance(self.axes, dict): @@ -2753,7 +2700,10 @@ def _keypress(self, iren, event): if hasattr(self.axes_instances[clickedr], "EnabledOff"): # widget self.axes_instances[clickedr].EnabledOff() else: - self.renderer.RemoveActor(self.axes_instances[clickedr]) + try: + self.renderer.RemoveActor(self.axes_instances[clickedr]) + except: + pass self.axes_instances[clickedr] = None addons.addGlobalAxes(axtype=asso[key], c=None) self.interactor.Render() diff --git a/vedo/pointcloud.py b/vedo/pointcloud.py index f5bf590f..6bbeac4d 100644 --- a/vedo/pointcloud.py +++ b/vedo/pointcloud.py @@ -850,14 +850,18 @@ def __init__( self._scals_idx = 0 # index of the active scalar changed from CLI self._ligthingnr = 0 # index of the lighting mode changed from CLI - if inputobj is None: - self._polydata = vtk.vtkPolyData() - return - ########## prp = self.GetProperty() - if hasattr(prp, 'RenderPointsAsSpheresOn'): + try: prp.RenderPointsAsSpheresOn() + except: + pass + + if inputobj is None:#################### + self._polydata = vtk.vtkPolyData() + return + ######################################## + prp.SetRepresentationToPoints() prp.SetPointSize(r) self.lighting(ambient=0.7, diffuse=0.3) diff --git a/vedo/settings.py b/vedo/settings.py index 1f8fcd51..c1ce1047 100644 --- a/vedo/settings.py +++ b/vedo/settings.py @@ -488,9 +488,9 @@ def embedWindow(backend='k3d', verbose=True): notebook_plotter = None return + backend = backend.lower() notebookBackend = backend - if backend=='k3d': try: import k3d @@ -512,9 +512,9 @@ def embedWindow(backend='k3d', verbose=True): print('> conda install nodejs') elif backend.lower() == '2d': - verbose=False + pass - elif backend=='panel': + elif backend =='panel': try: import panel panel.extension('vtk') @@ -524,7 +524,7 @@ def embedWindow(backend='k3d', verbose=True): print('> pip install panel -U # and/or') print('> conda install nodejs') - elif backend=='ipyvtk': + elif 'ipyvtk' in backend: try: from ipyvtk_simple.viewer import ViewInteractiveWidget except: diff --git a/vedo/shapes.py b/vedo/shapes.py index fad1eaee..083a6d37 100644 --- a/vedo/shapes.py +++ b/vedo/shapes.py @@ -2939,7 +2939,7 @@ class TextBase: def __init__(self): self.renderedAt = set() - + self.fontname = settings.defaultFont def angle(self, a): """Orientation angle in degrees""" @@ -3005,7 +3005,10 @@ def frame(self, color='k1', lw=1): self.property.SetFrameWidth(lw) return self - def font(self, font): + def font(self, font=None): + + if font is None: + return self.fontname if isinstance(font, int): lfonts = list(settings.font_parameters.keys()) @@ -3022,10 +3025,9 @@ def font(self, font): else: # user passing name of preset font fpath = settings.fonts_path + font +'.ttf' - tprop = self.property - if font == "Courier": tprop.SetFontFamilyToCourier() - elif font == "Times": tprop.SetFontFamilyToTimes() - elif font == "Arial": tprop.SetFontFamilyToArial() + if font == "Courier": self.property.SetFontFamilyToCourier() + elif font == "Times": self.property.SetFontFamilyToTimes() + elif font == "Arial": self.property.SetFontFamilyToArial() else: try: if not settings.font_parameters[font]['islocal']: @@ -3033,15 +3035,20 @@ def font(self, font): except: printc("Warning: could not download/set font", font, "-> Using default:", settings.defaultFont) - fpath = settings.fonts_path + settings.defaultFont +'.ttf' - tprop.SetFontFamily(vtk.VTK_FONT_FILE) - tprop.SetFontFile(fpath) + font = settings.defaultFont + fpath = settings.fonts_path + font +'.ttf' + self.property.SetFontFamily(vtk.VTK_FONT_FILE) + self.property.SetFontFile(fpath) + + self.fontname = font # io.toNumpy() uses it return self class Text2D(vtk.vtkActor2D, TextBase): """ - Returns a ``vtkActor2D`` representing 2D text. + Returns a 2D text object. + All properties of the text, and the text itself, can be changed after creation + (which is expecially useful in loops). :param pos: text is placed in one of the 8 positions: @@ -3092,7 +3099,7 @@ class Text2D(vtk.vtkActor2D, TextBase): |caption| """ def __init__(self, - txt, + txt="", pos="top-left", s=1, c=None, @@ -3186,7 +3193,7 @@ def text(self, txt=None): """Set/get the input text string""" if txt is None: - return self._mapper.GetText() + return self._mapper.GetInput() if "\\" in repr(txt): for r in _reps: diff --git a/vedo/utils.py b/vedo/utils.py index c9601535..6bb22730 100644 --- a/vedo/utils.py +++ b/vedo/utils.py @@ -1330,7 +1330,7 @@ def makeTicks(x0, x1, N, labels=None, digits=None): ticks_str, ticks_float = [], [] if x1 <= x0: - printc("Error in makeTicks(): x0 >= x1.", c='r') + # printc("Error in makeTicks(): x0 >= x1", x0,x1, c='r') return np.array([0.0,1.0]), ["",""] if labels is not None: diff --git a/vedo/version.py b/vedo/version.py index 1f13a711..9f3d93a8 100644 --- a/vedo/version.py +++ b/vedo/version.py @@ -1 +1 @@ -_version='2021.0.1' +_version='2021.0.2'