1
$\begingroup$

I have a face on a mesh and I want to create a cylinder where the faces around would perfectly fit on this given face, not taking in account the height of the cylinder.

I know the number of "vertices" (8). I have the size of the face I want to stick the cylinder on (0.399833).

How can I do that?

EDIT : Here's an image. I need to merge the two faces. enter image description here

$\endgroup$
6
  • $\begingroup$ I'm not sure what is "not taking in account the height of the cylinder", but could you add some reference images? E.g. how does that face look like? Is it supposed to be side face of cylinder or top one? $\endgroup$
    – Mr Zak
    Dec 30, 2017 at 18:52
  • $\begingroup$ I added an image $\endgroup$ Dec 30, 2017 at 19:16
  • $\begingroup$ So you mean you know scale of the front face of the cube on the left? And it's the one you'd like to create from it cylinder on the right? $\endgroup$
    – Mr Zak
    Dec 30, 2017 at 19:24
  • $\begingroup$ Yes, that's what I'm trying do to $\endgroup$ Dec 30, 2017 at 19:29
  • $\begingroup$ Then you can separate front face from the rest of the cube, set origin of resulting object to center of that face, remove one of edges of that face and use Array modifier based on empty to create a cylinder using arraying. See blender.stackexchange.com/questions/6023/… for examples of modiifer setup. Note that this way isn't deadly easy to setup if origin of the face is not set to its center prior to deleting another edge which is its downside. $\endgroup$
    – Mr Zak
    Dec 30, 2017 at 19:54

6 Answers 6

1
$\begingroup$

Here is a function that creates a polygon based on the number of edges and length of one edge.

  1. align your target object edge with the y axis
  2. get the exact length of the edge you want the polygon to align with
  3. modify the function call params
  4. run the script
  5. fill and extrude the resulting polygon

Based on this by @float: Possible to add a plane using vertices via Python?

import bpy
import math
from math import radians

# thanks to "float"
# https://blender.stackexchange.com/questions/67517/possible-to-add-a-plane-using-vertices-via-python
def create_segmented_loop_by_edge_length(objname, px, py, pz, edge_length, number_of_segments ):

    # Define arrays for holding data    
    myvertex = []
    edges = []

    # Create all Vertices
    segment_length_angle = 2*math.pi / number_of_segments

    #starting pt
    mypoint = [(0.0, 0.0, 0.0)]
    myvertex.extend(mypoint)

    for i in range(1,number_of_segments+1):
        angle = (2-i) * segment_length_angle
        dx = (edge_length * math.cos(angle) )
        dy = (edge_length * math.sin(angle) )
        mypoint = [( mypoint[0][0] + dx, mypoint[0][1] + dy, 0.0 )]
        myvertex.extend(mypoint)

        edge = [( i-1, i )]
        edges.extend(edge)

    mymesh = bpy.data.meshes.new(objname)
    myobject = bpy.data.objects.new(objname, mymesh)
    bpy.context.scene.objects.link(myobject)

    # Generate mesh data
    mymesh.from_pydata(myvertex, edges, [])

    # Set Location
    myobject.location.x = px
    myobject.location.y = py
    myobject.location.z = pz

    return myobject
#################################################

#Example:    
curloc = bpy.context.scene.cursor_location
create_segmented_loop_by_edge_length("mysegmentedcircle", curloc[0], curloc[1], 0, 1.0,8)

enter image description here

$\endgroup$
1
$\begingroup$

OK, I assume you need the box to stay the same size and want an octagon that has the right size or else Bastian's answer would be best. I also assume that you want a really clean result because one could simply scale around the cursor (with the cursor sitting on a vertex of the box and the box snapped to the box using the magnet), getting it roughly right and then zoom all the way in to do the fine adjustment.

enter image description here

I tried to use snapping while scaling it but somehow Blender steadily refuses to bend to my will. So I use a more predictable approach.

I set the magnet to vertex and closest. Then I go into the editmode of the box, select the right face and duplicate it. I rotate the face by 45 degrees (R45Return) and then move it holding ctrl so the magnet snaps it to the edge of the box. It's sometimes easier to roughly position the face first without snapping so that Blender gets which verts are supposed to be closest. I repeat to snap rotated faces until I have the octagon.

After that I hit remove doubles and fill the edgeloops and delete the inside face so the mesh stays manifold. I also select all verts and hit ctrl-N to recalc the normals

enter image description here

An array modifier would of course work, too.

$\endgroup$
0
$\begingroup$

If you know the circunference you can have blender calculate the radius.

The formula is simple:

r = C / (pi x 2)

For example for a cylinder that is 20 cm in diameter, just type:

20cm/(2*pi) as radius

enter image description here

$\endgroup$
5
  • $\begingroup$ this is not about knowing the radius but rather knowing the lenght of one polygon edge $\endgroup$
    – Bruno
    Feb 3, 2018 at 6:51
  • 2
    $\begingroup$ This is for those who want to know "How to create a cylinder with a given circumference?" as the title of the question says... $\endgroup$
    – user1853
    Feb 3, 2018 at 18:24
  • $\begingroup$ you are right... but that means the question is not formulated properly! I've asked the author to change it. $\endgroup$
    – Bruno
    Feb 4, 2018 at 9:02
  • $\begingroup$ @cegaton Well, if you ignore the body of the question, then your answer is perfectly fine. Although you could use the formula for an octagon, then it would actually be correct either way. $\endgroup$ Feb 11, 2018 at 20:41
  • $\begingroup$ @cegaton since he talked about a cylinder with 8 verts (dunno if that was added later), PI doesn't help much. It gets even a bit more complicated since the size of the octagon isn't 2 anymore once you rotate itso it can be attached. It's 1.838something. $\endgroup$ Feb 11, 2018 at 20:51
0
$\begingroup$

I stumbled upon the right answer and it doesn't really fit into my old one, so I think a separate try is more useful:

Create your two objects, rotate the cylinder 22.5 degrees if necessary, then switch on snapping, set it to Vertex and Active. Snapping to the active vertex is what makes it controllable.

enter image description here

Go into editmode of the cylinder. SHIFTRMB the upper left vertex to make it the active (white) one. That might be easier if you rotate the view so the verts don't overlap. Now move it to the cube until it snaps and confirm.

enter image description here

SHIFTS Cursor to Active. Set the pivot point to '3D Cursor'.

Keep all verts selected, but now make the bottom left the active one.

Scale around the cursor until it snaps (keep the mouse close to the target corner of the cube), then confirm.

enter image description here

And now they should be exactly the same size. Return to object mode, select the lesser of them, then shift select the one that's supposed to keep the object origin and join them with CtrlJ.

Remove doubles, then remove the trapped face and you have joind them. Maybe recalculate normals is needed, too.

$\endgroup$
0
$\begingroup$

Bmesh edit mode

In edit mode, Select the quad you wish to make a cylinder edge segment and run script. Change sides = 8 to amount of sides needed. The script dupes the active face, and uses shortest end to make cylinder sides and spins around the axis made by the longest face with center calculated using half angle tangent formula.

Removes the inner face. Doesn't cap the ends.

import bpy
import bmesh
from math import radians, tan
from mathutils import Matrix
sides = 8
angle = radians(360 / sides)
halfangle = angle / 2
context = bpy.context
ob = context.edit_object
me = ob.data
bm = bmesh.from_edit_mesh(me)
f = bm.faces.active
edges = sorted(f.edges,
    key=lambda e: e.calc_length())
side = edges[0].calc_length()

le = edges[-1]
diameter = side / (2 * tan(halfangle))
axis = (le.verts[1].co - le.verts[0].co).normalized()
center = f.calc_center_median() + diameter * f.normal

dupe = bmesh.ops.duplicate(bm, geom=[f])

geom = [f for f in dupe["geom"] if isinstance(f, bmesh.types.BMFace)]
[f.normal_flip() for f in geom]
spin = bmesh.ops.spin(bm, 
        geom=geom, 
        cent=center, 
        axis=axis,  
        angle=(sides - 1) * angle,
        #angle=radians(360), 
        steps=sides - 1, 
        use_duplicate=True)
bm.faces.remove(f)
bm.faces.remove(geom[0])
bmesh.ops.remove_doubles(bm, 
        verts = bm.verts,
        dist = 0.00001,
        )

bmesh.update_edit_mesh(me)

Result of sample run, with sides = 8

enter image description here

$\endgroup$
-1
$\begingroup$

My solution would be to create the cylinder first and then extrude one of the faces if I understand your question correctly.

$\endgroup$
2
  • 1
    $\begingroup$ I think it should be a comment rather than question. $\endgroup$
    – cgslav
    Dec 30, 2017 at 23:34
  • $\begingroup$ It's not a question... And not all people can comment. You need some reputation, which I didn't have back then @cgslav $\endgroup$ May 2, 2023 at 15:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .