1
$\begingroup$

I'm a noob in blender scripting. I ended up here after trying to make a suitable star tetrahedron for 3d printing (will split it in 3 separate parts) by just modeling it or sculpt it. I failed and couldn't find help anywhere. The idea is to make this smooth model without the hooks and corner bulges. http://ep.yimg.com/ay/toolsforwellnesscom/star-tetrahedron-3.jpg Found some old code for just one tetrahedron but it has rough cylinders and no corners.

import bpy
from math import sqrt
from mathutils import Vector


def cylinder(a, b, radius=1.0):
    depth = (a-b).length
    location = a.lerp(b, 0.5)
    rotation = Vector((0, 0, 1)).rotation_difference(a-b).to_euler()

    bpy.ops.mesh.primitive_cylinder_add(
        depth=depth,
        location=location,
        rotation=rotation,
        radius=radius)


def tetrahedron_frame(radius=0.1, scale=1.0):
    s = sqrt(2)/3*scale
    t = -1/3*scale
    u = sqrt(6)/3*scale

    v = [(0, 0, scale), (2*s, 0, t), (-s, u, t), (-s, -u, t)]

    cylinder(Vector(v[0]), Vector(v[1]), radius=radius)
    cylinder(Vector(v[0]), Vector(v[2]), radius=radius)
    cylinder(Vector(v[0]), Vector(v[3]), radius=radius)
    cylinder(Vector(v[1]), Vector(v[2]), radius=radius)
    cylinder(Vector(v[2]), Vector(v[3]), radius=radius)
    cylinder(Vector(v[3]), Vector(v[1]), radius=radius)


tetrahedron_frame()

Any ideas on how to make this happen?

$\endgroup$
6
$\begingroup$

Scripting probably isn't a good option. That particular script just creates a bunch of cylinder objects and aligns them to approximate a tetrahedron. This isn't good topology and is most definitely not 3d-printable. To create a script that would actually do that, you would probably need to use the bmesh api.

This here isn't scripting, but is an easy way to model a star tetrahedron than programming it.

Step 1: Add a cone. Set the vertices to 3 and the the depth to sqrt(2) (Blender will automatically parse it).

enter image description here

Step 2: Go into Edit Mode, select everything, and hit W > Subdivide. Select all of the center faces and click Extrude Individual in the sidebar, then hit Enter without moving the mouse.

enter image description here

Step 3: Set the Pivot Center to Individual Origins.

enter image description here

Step 4: Press S, then 0, then Enter to collapse the faces down to vertices.

enter image description here

Step 5: In the sidebar, press Remove Doubles.

Step 6: Change the Pivot Center back to Median Point.

Step 7: With just the center vertices selected, press S, then 3, then Enter to move out the points.

enter image description here

If you want to make it a wireframe like your reference image, you can use a wireframe modifier:

enter image description here

And you can smooth it out with some tweaking of settings and some SubSurf modifiers.

enter image description here

$\endgroup$
  • $\begingroup$ That's exactly what I was going to tell him...scripting isn't really the best option here... $\endgroup$ – JakeD Feb 21 '17 at 23:47
  • $\begingroup$ Wow, thaw was great help. One thing is missing though: the wireframe isn't round and the poligonal shape of the edges is a pain in the ass to print if it isn't like a cylinder. $\endgroup$ – Horia Ioan Feb 22 '17 at 22:09
  • $\begingroup$ I ended up using this method because I found a way to orientate the model as to be 3d printed without supports. Thanks again! $\endgroup$ – Horia Ioan Mar 15 '17 at 0:10
2
$\begingroup$

Script version of @Scott Milner's Answer

May be of interest to others on how to create a script using a method gleaned from the UI. Creates a solid mesh as shown in step 7. I have used poke to get to step 4.

To keep track of results from operators the centres of the original tetra faces are kept. After subdivide he triangles with the same centres will be poked. After poke the verts with the same coordinate will be scaled out.

enter image description here

import bpy
import bmesh
from math import sqrt
from mathutils import Vector

context = bpy.context
scene = context.scene
me = bpy.data.meshes.new("tetstar")
bm = bmesh.new()
bm.from_mesh(me)
TOL = 0.001
# add triangle cone
bmesh.ops.create_cone(bm,
        diameter1=1,
        diameter2=0,
        cap_ends=True,
        depth=sqrt(2),
        segments=3)
# fix the origin
o = sum((v.co for v in bm.verts), Vector()) / len(bm.verts)
for v in bm.verts:
    v.co -= o
# keep track of centres.
centres = [f.calc_center_median() for f in bm.faces]
sub = bmesh.ops.subdivide_edges(bm,
        edges=bm.edges,
        use_grid_fill=True,
        use_single_edge=True,
        cuts=1)
# use original tetra faces to find sub middle faces  
new_faces = [f for f in sub["geom_inner"] 
        if isinstance(f, bmesh.types.BMFace)
        and any((f.calc_center_median() - c).length < TOL for c in centres) ]
# and poked vert
poke = bmesh.ops.poke(bm, faces=new_faces)
verts = [v for v in poke["verts"] 
        if any((v.co - c).length < TOL for c in centres)]    
# scale them out
for v in verts:
    v.co *= 3
# write mesh and create object.    
bm.to_mesh(me) 
ob = bpy.data.objects.new("TetraStar", me)
scene.objects.link(ob)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.