procedural mesh creation with blender script - blender

What is a clean way to create a procedural mesh in blender with a script? Ideally I'd like to create an empty mesh and start adding vertices and triangles, like this:
mesh = create_mesh()
a = mesh.add_vertex([0, 0, 0])
b = mesh.add_vertex([1, 0, 0])
c = mesh.add_vertex([1, 1, 0])
t = mesh.add_triangle(a, b, c)

Blenders bmesh module is designed for creating and editing mesh data, although you can also turn python arrays into mesh data.
You can find some examples included with blender, all addons are made using python, one helpful addon would be add_mesh_extra_objects which has several examples of creating different types of objects.
There is a blender specific stackexchange site where you will get more help with blender specific scripting. You should also find some existing examples there.

Related

Multiple axis scale in Lets plot Kotlin

I'm learning some data science related topics and oh boy, this is a jungle of different libraries for everything 😅
Because of things, I went with Lets-plot, which has a nice Kotlin API that I'm using combined with Kotlin kernel for Jupyter notebooks
Overall, things are going pretty good. Most tutorials & docs I see online use different libraries for plotting (e.g. Seaborn, Matplotlib, Plotly) so most of the time I have to do some reading of the Lets-Plot-Kotlin reference and try/error until I find the equivalent code for my graphs
Currently, I'm trying to graph the distribution of differences between two values. Overall, this looks pretty good. I can just do something like
(letsPlot(df)
+ geomHistogram { x = "some-column" }
).show()
which gives a nice graph
It would be interesting to see the density estimator as well, geomDensity to the rescue!
(letsPlot(df)
+ geomDensity(color = "red") { x = "some-column" }
).show()
Nice! Now let's watch them both together
(letsPlot(df)
+ geomDensity(color = "red") { x = "some-column" }
+ geomHistogram() { x = "some-column" }
).show()
As you can see, there's a small red line in the bottom (the geomDensity!). Problem here (I would say) is that both layers are using the same Y scale. Histogram is working with 0-20 values and density with 0-0.02 so when plotted together it's just a line at the bottom
Is there any way to add several layers in the same plot that use their own scale? I've read some blogposts that claim that you should not go for it (seems to be pretty much accepted by the community.
My target is to achieve something similar to what you can do with Seaborn by doing
plt.figure(figsize=(10,4),dpi=200)
sns.histplot(data=df,x='some_column',kde=True,bins=25)
(yes I know I took the lets plot screenshot without the bins configured. Not relevant, I'd say ¯_(ツ)_/¯ )
Maybe I'm just approaching the problem with a mindset I should not? As mentioned, I'm still learning so every alternative will be highly welcomed 😃
Just, please, don't go with the "Switch to Python". I'm exploring and I'd prefer to go one topic at a time
In order for histogram and density layers to share the same y-scale you need to map variable "..density.." to aesthetic "y" in the histogram layer (by default histogram maps "..count.." to "y").
You will find an example of it in cell [4] in this notebook: https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/distributions.ipynb
BWT, many of the pages in Lets-Plot Kotlin API Reference are equipped with links on demo-notebooks, in "Examples" section: geomHistogram().
And of course you can find a lot of info online on the R ggplot2 package which is largely applicable to Lets-Plot as well. For example: Histogram with kernel density estimation.
Finally :) , calling show() is not necessary - Jupyter Kotlin kernel will render plot automatically if plot expression is the last one in the cell which is often the case.

Is there any way to access blender defined vertex group in Godot?

I'm trying to automate SoftBody creation in Godot. Everything is working perfect except for the part were I'm supposed to supply pinned points for mesh.
var node = SoftBody.new()
node.pinned_points = [] #This is the array where I'm supposed to supply vertex id like: [1, 45, 1142]
Those are the vertex points that keep mesh hold position. Now since I'll use script for multiple models I can't use Godot editor for that purpose. So I thought I'll make an additional group in blender vertex group and access those vertices in Godot but I don't know the HOW part. Is there any alternative way? I'm open to ideas. Thanks!

Create single mesh for multiple bodies in GMSH

I am currently trying to do a magnetostatic FEM simulation and I want to mesh my geometry using GMSH. The geometry is shown below: in
I create the geometry using FreeCAD and import into GMSH as a .STEP File. In GMSH I define 3 physical groups, resulting in the following script:
Merge "yoke_simulation.step";
Physical Volume("iron") = {1, 7, 9, 6, 3, 2, 4};
//+
Physical Volume("current") = {5};
//+
Physical Volume("air") = {8};
When I create the Mesh, I get the following result:
The problem is that GMSH seems to be creating a seperate mesh for each body without connecting these meshes with one another. If one looks at the region between the two cones for example, it is evident that the mesh of the two cones is not connected to the mesh of the air:
How can I get GMSH to create a single, connected mesh for all bodies?
It seems that right now the Air volume 8 is just the overall bounding box, without necessary subtraction of volumes for Iron and Current. Thus, it creates a tetrahedral mesh for the entire bounding box without taking other bodies into the account.
I am not a FreeCAD expert, so I don't really know how to setup it properly there. Possibly, try specifying the Air volume there making sure it does not contain your detail.
Another approach could involve slight modifications at the GMSH level. For example, creating the proper Air volume before making it physical. You have volumes 1, 7, 9, 6, 3, 2, 4, 5 which you want to subtract from volume 8. That can be achieved by
BooleanDifference(100) = { Volume{8}; Delete; }{ Volume{1,7,9,6,3,2,4,5}; };
Physical Volume("air") = {100};
Notice, that the previous code will work only if OpenCASCADE kernel inside GMSH is used.
Please, see the following sample code in GMSH for reference:
SetFactory("OpenCASCADE");
Box(1) = {0,0,0, 1,1,1};
Box(2) = {0.1,0.1,0.1, 0.2,0.2,0.2};
Box(3) = {0.5,0.5,0.5, 0.2,0.2,0.2};
BooleanDifference(100) = { Volume{1}; Delete; }{ Volume{2,3}; };
Physical Volume ("air") = {100};
Physical Volume ("iron") = {2,3};
Dropping the command Coherence; after the merge line will force GMSH to form a coherent mesh without overlapping volumes.
I have created a set of free-and-open-source tools to generate partitioned meshes for multi-material FEM.
They are available here
github.com/NH89/SOFA_mesh_partitioning_tools
The are based on the CGAL geometry library, and generate a partitioned tetrahedral mesh from arbitrary intersecting triangulated surface meshes.
They are conceived for use with the SOFA real-time soft matter FEM framework, but could be used for any partitioned FEM application.

VTK / ITK Dice Similarity Coefficient on Meshes

I am new to VTK and am trying to compute the Dice Similarity Coefficient (DSC), starting from 2 meshes.
DSC can be computed as 2 Vab / (Va + Vb), where Vab is the overlapping volume among mesh A and mesh B.
To read a mesh (i.e. an organ contour exported in .vtk format using 3D Slicer, https://www.slicer.org) I use the following snippet:
string inputFilename1 = "organ1.vtk";
// Get all data from the file
vtkSmartPointer<vtkGenericDataObjectReader> reader1 = vtkSmartPointer<vtkGenericDataObjectReader>::New();
reader1->SetFileName(inputFilename1.c_str());
reader1->Update();
vtkSmartPointer<vtkPolyData> struct1 = reader1->GetPolyDataOutput();
I can compute the volume of the two meshes using vtkMassProperties (although I observed some differences between the ones computed with VTK and the ones computed with 3D Slicer).
To then intersect 2 meshses, I am trying to use vtkIntersectionPolyDataFilter. The output of this filter, however, is a set of lines that marks the intersection of the input vtkPolyData objects, and NOT a closed surface. I therefore need to somehow generate a mesh from these lines and compute its volume.
Do you know which can be a good, accurate way to generete such a mesh and how to do it?
Alternatively, I tried to use ITK as well. I found a package that is supposed to handle this problem (http://www.insight-journal.org/browse/publication/762, dated 2010) but I am not able to compile it against the latest version of ITK. It says that ITK must be compiled with the (now deprecated) ITK_USE_REVIEW flag ON. Needless to say, I compiled it with the new Module_ITKReview set to ON and also with backward compatibility but had no luck.
Finally, if you have any other alternative (scriptable) software/library to solve this problem, please let me know. I need to perform these computation automatically.
You could try vtkBooleanOperationPolyDataFilter
http://www.vtk.org/doc/nightly/html/classvtkBooleanOperationPolyDataFilter.html
filter->SetOperationToIntersection();
if your data is smooth and well-behaved, this filter works pretty good. However, sharp structures, e.g. the ones originating from binary image marching cubes algorithm can make a problem for it. That said, vtkPolyDataToImageStencil doesn't necessarily perform any better on this regard.
I had once impression that the boolean operation on polygons is not really ideal for "organs" of size 100k polygons and more. Depends.
If you want to compute a Dice Similarity Coefficient, I suggest you first generate volumes (rasterize) from the meshes by use of vtkPolyDataToImageStencil.
Then it's easy to compute the DSC.
Good luck :)

Selective patterns with Matplotlib imshow without using patches

Is there a way to place patterns into selected areas on an imshow graph? To be precise, I need to make it so that, in addition to the numerical-data-carrying colored squares, I also have different patterns in other squares indicate different failure modes for the experiment (and also generate a key explaining the meaning of these different patterns). An example of a pattern that would be useful would be various types of crosshatches. I need to be able to do this without disrupting the main color-numerical data relationship on the graph.
Due to the back-end I am working within for the GUI containing the graph, I cannot utilize patches (they fail to pickle and make it from the back-end to the front-end via the multiprocessing package). I was wondering if anyone knew of another way to do this.
grid = np.ma.array(grid, mask=np.isnan(grid))
ax.imshow(grid, interpolation='nearest', aspect='equal', vmax = private.vmax, vmin = private.vmin)
# Up to here works fine and draws the graph showing only the data with white spaces for any point that failed
if show_fail and faildat != []:
faildat = faildat[np.lexsort((faildat[:,yind],faildat[:,xind]))]
fails = []
for i in range(len(faildat)): #gives coordinates with failures as (x,y)
fails.append((faildat[i,1],faildat[i,0]))
for F in fails:
ax.FUNCTION NEEDED HERE
ax.minorticks_off()
ax.set_xticks(range(len(placex)))
ax.set_yticks(range(len(placey)))
ax.set_xticklabels(placex)
ax.set_yticklabels(placey, rotation = 0)
ax.colorbar()
ax.show()