diff --git a/Lattesh/README.md b/Lattesh/README.md
index f28de14a92d4cf15de3e3a70db8b054d1586a010..dc6d6e568eecd9c80b4da7b35755fef91d0c1046 100644
--- a/Lattesh/README.md
+++ b/Lattesh/README.md
@@ -60,6 +60,8 @@ side bar of the 3D Viewport. The panel is depicted below.
 
 ![Panel image](doc/side_panel.png)
 
+#### Rectangular lattice generation
+
 The top part contains the parameters for regular lattice generation. The 
 parameters are:
  - **Cell size**: the length defining the individual cells. 
@@ -70,18 +72,41 @@ parameters are:
 Clicking on the **Create Mesh Lattice** will create a rectangular lattice with 
 these parameters. 
 
+#### Filling a volume with lattice
+
 If a mesh object is selected, clicking on **Fill Mesh Lattice** will create a 
-regular lattice of *cell size* and *cell type* that fills the selected object.
+regular lattice of *cell size* and *cell type* that fills the selected object. 
+The boolean intersection algorithm is experimental and can fail. In that case, 
+a lattice is still created and must be manually edited to remove the parts outside
+the target mesh.
+
+#### Cylindrical struts
 
 If a lattice is selected (or any mesh object), an **Opencascade fill** menu is
 available. Upon clicking on **Lattice Volume (OCC)**, the lattice will be given
 a volume, where for each edge in the original object a cylindrical strut will 
-be created. The strut radius is available as an input parameter.
+be created. The strut radius is available as an input parameter. 
 
 This operation will take only some seconds for very regular lattices, but a large
 irregular lattice can take several hours to process. In this case, the add-on prints
 messages on the terminal relating the progress.
 
+#### Variable strut radius
+
+It is possible to generate struts with varing thickness in a single lattice. To
+that end, the mesh must have a float attribute called *radius*, with domain *'POINTS'*.
+When such a parameter is present in the selected mesh, an extra option,
+*Variable radius*, becomes usable. When checked, the radius of the generated mesh
+at each lattice node will be given by this parameter.
+
+The *radius* parameter can be generated using [geometry nodes](https://docs.blender.org/manual/en/latest/modeling/geometry_nodes/index.html)
+in Blender. An example is shown below.
+
+![Nodes example](doc/nodes.png)
+
+![Variable radius mesh](doc/result.png)
+
+
 ### Installation
 
 The Add-on is installed as usual in Blender via the *Preferences* menu. However, 
diff --git a/Lattesh/__init__.py b/Lattesh/__init__.py
index 63eef4a2671ca9f2c488b9367f3bd41a3c847d84..faeba14bf1722ef8840acb5ff869f9084fa6c0f7 100644
--- a/Lattesh/__init__.py
+++ b/Lattesh/__init__.py
@@ -21,7 +21,7 @@
 
 
 bl_info = {
-    "name": "Lattice Tools",
+    "name": "Lattesh - Lattice Tools",
     "author": "Ubiratan S. Freitas",
     "blender": (2, 80, 0),
     "description": "Tools for generating lattice structures",
@@ -65,7 +65,7 @@ class SceneProperties(PropertyGroup):
     r_ratio: FloatProperty(
         name="R_ratio",
         description="Ratio of actual radius to metaball radius",
-        default=0.8, 
+        default=0.65, 
         min=0.01,
         max=0.99,
     )
@@ -108,6 +108,13 @@ class SceneProperties(PropertyGroup):
         default=False,
     )
 
+    variable_radius: BoolProperty(
+        name="Variable radius",
+        description="Variable strut radius using 'radius' attribute from mesh",
+        default=False,
+    )
+
+
     charac_length: FloatProperty(
         name="Caracteristic length",
         description="Caracteristic length",
diff --git a/Lattesh/doc/nodes.png b/Lattesh/doc/nodes.png
new file mode 100644
index 0000000000000000000000000000000000000000..7256c1ef21f6cfdef13c25616d25898f65e619a8
Binary files /dev/null and b/Lattesh/doc/nodes.png differ
diff --git a/Lattesh/doc/result.png b/Lattesh/doc/result.png
new file mode 100644
index 0000000000000000000000000000000000000000..013418e164268d73a869e9504bda2a552a32e60b
Binary files /dev/null and b/Lattesh/doc/result.png differ
diff --git a/Lattesh/doc/side_panel.png b/Lattesh/doc/side_panel.png
index 529b5349e154a92c4d2f5581b5881e12488e3a30..4cd5c06f547603152a1952b4f5fe56c935db3f22 100644
Binary files a/Lattesh/doc/side_panel.png and b/Lattesh/doc/side_panel.png differ
diff --git a/Lattesh/operators.py b/Lattesh/operators.py
index 3b0e8fbe63e59506c9bc70413a1d8883dd93dd0b..2ca9e04feb96101f90aa41a4037fd66da28a6c4b 100644
--- a/Lattesh/operators.py
+++ b/Lattesh/operators.py
@@ -799,10 +799,9 @@ def occ_compute_node(ev, r=0.5, mesh_pars=(0.1, False, math.radians(60), False),
 
 
 
-def createMesh(target, r=0.5, lin_deflect=0.1, ang_deflect=math.radians(60.)):
-    """Gives a volume to each edge in target using cylinders of radius r and nsides sides"""
+def createMesh(target, r=0.5, var_radius=False, lin_deflect=0.1, ang_deflect=math.radians(60.)):
+    """Gives a volume to each edge in target using cylinders of radius r"""
     min_angle = math.radians(30)
-    min_length = r / math.tan(min_angle / 2.0)
     quantization = 100
     tmesh = target.data
     name = target.name + "Cyl"
@@ -811,6 +810,22 @@ def createMesh(target, r=0.5, lin_deflect=0.1, ang_deflect=math.radians(60.)):
     
     verts = np.empty(nverts * 3, dtype=np.float32)
     edges = np.empty(nedges * 2, dtype=np.int32)
+    var_radius = var_radius and 'radius' in tmesh.attributes
+    if var_radius :
+        std_r = 0.5
+        radius = np.empty(nverts, dtype=np.float32)
+        tmesh.attributes['radius'].data.foreach_get('value', radius)
+        dia = ' {:.1f}-{:.1f}'.format(radius.min() * 2, radius.max() * 2)
+        # prescale the radius
+        radius /= std_r
+    else:
+        std_r = r
+        radius = np.full(nverts, r, dtype=np.float32)
+        dia = ' {:.1f}'.format(r * 2)
+    name += dia
+
+    min_length = radius / math.tan(min_angle / 2.0)
+    
 
     tmesh.vertices.foreach_get('co', verts)
     tmesh.edges.foreach_get('vertices', edges)
@@ -840,7 +855,7 @@ def createMesh(target, r=0.5, lin_deflect=0.1, ang_deflect=math.radians(60.)):
 
     mesh = bpy.data.meshes.new(name+'Mesh')
 
-    print(f'{nedges} total edges, {len(dqedges)} quantized orientations, {min_length:.2f}, minimal edge length.')
+    print(f'{nedges} total edges, {len(dqedges)} quantized orientations, {min_length.max():.2f}, minimal edge length.')
 
     
     # Generate all possible edge orientations, including reverse
@@ -884,7 +899,7 @@ def createMesh(target, r=0.5, lin_deflect=0.1, ang_deflect=math.radians(60.)):
             continue
         if len(nodes[k]) == 1:
             single_nodes.add(k)
-            if edge_len[nodes[k][0][0]] < min_length:
+            if edge_len[nodes[k][0][0]] < min_length[k]:
                 # Discard single nodes with small edge length
                 discarded_edges.add(nodes[k][0])
                 continue
@@ -893,7 +908,7 @@ def createMesh(target, r=0.5, lin_deflect=0.1, ang_deflect=math.radians(60.)):
         for kk, eddir in nodes[k]:
             if kk in discarded_edges:
                 continue
-            if edge_len[kk] < min_length:
+            if edge_len[kk] < min_length[k]:
                 if len(nodes[edges[kk, int(eddir)]]) == 1:
                     # Discard single nodes with small edge length
                     discarded_edges.add(kk)
@@ -935,11 +950,11 @@ def createMesh(target, r=0.5, lin_deflect=0.1, ang_deflect=math.radians(60.)):
         # Compute node geomery with Opencascade
         try:
             retry_count = 0
-            node_verts, node_faces, node_nsides, node_edverts, shape = occ_compute_node(ev, r, mesh_pars=(lin_deflect, False, ang_deflect, False))
+            node_verts, node_faces, node_nsides, node_edverts, shape = occ_compute_node(ev, std_r, mesh_pars=(lin_deflect, False, ang_deflect, False))
             while len(node_edverts) != len(nt) and retry_count < 20:
                 retry_count += 1
                 print(f'Wrong number of edge verts in processed node {k} with {len(nt)} edges and {len(node_edverts)} found edges. Retry nb. {retry_count}.', end='\r')
-                node_verts, node_faces, node_nsides, node_edverts, shape = occ_compute_node(ev, r, mesh_pars=(lin_deflect, False, ang_deflect, False), shuffle=True)
+                node_verts, node_faces, node_nsides, node_edverts, shape = occ_compute_node(ev, std_r, mesh_pars=(lin_deflect, False, ang_deflect, False), shuffle=True)
             if retry_count > 0:
                 print()
         except:
@@ -971,7 +986,11 @@ def createMesh(target, r=0.5, lin_deflect=0.1, ang_deflect=math.radians(60.)):
                 # Translate the vertices of each node type to the actual position of the nodes and
                 # insert them in newverts
                 if verts_per_node:
-                    newverts[vert_count:vert_count + verts_per_node, :] = node_verts + verts[n,:]
+                    if var_radius:
+                        temp_verts = node_verts * radius[n]
+                    else:
+                        temp_verts = node_verts
+                    newverts[vert_count:vert_count + verts_per_node, :] = temp_verts + verts[n,:]
                 # Insert the node type faces in newfaces for each of the node instances
                 if faces_per_node:
                     newfaces[face_count:face_count + faces_per_node, :] = node_faces + vert_count
@@ -1046,7 +1065,7 @@ def createMesh(target, r=0.5, lin_deflect=0.1, ang_deflect=math.radians(60.)):
 
 
     # Link object to scene
-    bpy.context.scene.collection.objects.link(newobj)
+    bpy.context.collection.objects.link(newobj)
 
     
 
@@ -1054,12 +1073,12 @@ def createMetaball(target,  r=0.5, p=0.9):
     if target.type != 'MESH':
         return
     
-    name = target.name + "Rod"
+    name = target.name + "Rod {:.1f}".format(r * 2)
     print("Creating", name)
 
     metaball = bpy.data.metaballs.new(name+'Meta')
     obj = bpy.data.objects.new(name, metaball)
-    bpy.context.scene.collection.objects.link(obj)
+    bpy.context.collection.objects.link(obj)
     stiffness = 10.0
     
     # clip p
@@ -1141,7 +1160,8 @@ class ObjectOCCLattice(bpy.types.Operator):
 
     def execute(self, context):
         lattice_mesh = context.scene.lattice_mesh
-        createMesh(context.active_object, lattice_mesh.radius, lattice_mesh.lin_deflect, lattice_mesh.ang_deflect)
+        depsgraph = context.evaluated_depsgraph_get()
+        createMesh(context.active_object.evaluated_get(depsgraph), lattice_mesh.radius, lattice_mesh.variable_radius, lattice_mesh.lin_deflect, lattice_mesh.ang_deflect)
         return {'FINISHED'}
 
 
@@ -1173,7 +1193,7 @@ class ObjectCreateMeshLattice(bpy.types.Operator):
         newobj  = bpy.data.objects.new(name, mesh)
 
         # Link object to scene
-        bpy.context.scene.collection.objects.link(newobj)
+        bpy.context.collection.objects.link(newobj)
 
         return {'FINISHED'}
 
@@ -1214,7 +1234,7 @@ class ObjectFillMeshLattice(bpy.types.Operator):
         newobj.matrix_world = obj.matrix_world.copy()
 
         # Link object to scene
-        bpy.context.scene.collection.objects.link(newobj)
+        bpy.context.collection.objects.link(newobj)
 
         return {'FINISHED'}
 
@@ -1252,7 +1272,7 @@ class ObjectFillVoronoiLattice(bpy.types.Operator):
         newobj.matrix_world = obj.matrix_world.copy()
 
         # Link object to scene
-        bpy.context.scene.collection.objects.link(newobj)
+        bpy.context.collection.objects.link(newobj)
 
         return {'FINISHED'}
 
diff --git a/Lattesh/ui.py b/Lattesh/ui.py
index 967402207ad19afa35d5589cd8c3dcef82aa3775..aff1b9a49e1f86b47b33299cce5ee7276190beb6 100644
--- a/Lattesh/ui.py
+++ b/Lattesh/ui.py
@@ -85,11 +85,19 @@ class VIEW3D_PT_lattice_OCC(View3DLatticePanel, Panel):
 
     def draw(self, context):
         lattice_mesh = context.scene.lattice_mesh
+        depsgraph = context.evaluated_depsgraph_get()
+        has_radius = 'radius' in context.active_object.evaluated_get(depsgraph).data.attributes
 
         layout = self.layout
-        row = layout.row(align=True)
-        row.label(text="Strut radius")
-        row.prop(lattice_mesh, "radius", text="")
+        radius_row = layout.row(align=True)
+        radius_row.label(text="Strut radius")
+        radius_row.prop(lattice_mesh, "radius", text="")
+        if has_radius and lattice_mesh.variable_radius:
+            radius_row.enabled = False
+        var_row = layout.row(align=True)
+        var_row.label(text="Variable radius")
+        var_row.prop(lattice_mesh, "variable_radius", text="")
+        var_row.enabled = has_radius
         row = layout.row(align=True)
         row.label(text="Linear deflection")
         row.prop(lattice_mesh, "lin_deflect", text="")