2
$\begingroup$

I have an existing model I've built up which currently has cubic geometry and fits neatly inside a cube. This was built up in Blender manually by duplication, not by scripting, in case you're curious about that.

blender screenshot of the model

I'd now like to map the vertices to fit the thing inside a cylinder.

In 2D, this turns out to be called a Schwarz-Christoffel mapping.

Schwarz-Christoffel mapping

Is there a straightforward way to deform my existing model in this fashion without going back to the start and writing a script to generate the object? I think I could probably knock out a script to generate an OBJ file if I had a day to do it, but I feel like Blender might have an even faster option that lets me reuse my existing geometry.

I've been looking through all the "Deform" modifiers but nothing seems to jump out as immediately appropriate except for Cast, but I can't seem to get that one to do what I want either.

Edit:

For the next person hunting this out, the transformation I'm actually going with:

https://gist.github.com/trejkaz/222f687ef394f7430517868b254dc1b6

$\endgroup$
1
  • $\begingroup$ I'm not sure it anwsers because I'm not sure about what you mean by "map the vertices" but with the Surface Deform modifier you can get a cylinder from your cube, and if you want to keep the central grid just make a group of it and select it in the modifier $\endgroup$
    – moonboots
    Commented Aug 25, 2020 at 11:04

3 Answers 3

6
$\begingroup$

Squircle and shapekey

enter image description here Subdivided cube run thru script to give squircle generated cylinder shapekey.

In How can I morph a flat plane to be a flat cirlce? I have shown one of a number of square to circle mappings.

The mapping maps XY coords to a radius 1 circle, result shown above using default cube. For radius not equal to one would have to scale and rescale accordingly, or make radius an argument of mapping.

Note: This is the squircle mapping, as demonstrated I did go thru and provide an example of all the mappings, if I find the file will add the conformal mapping. As explained in link in linked answer.

import bpy
import bmesh
from math import sqrt
from bpy import context
collection = context.collection
ob = context.object
me = ob.data
def squircle(x, y):
    u = x * sqrt(1 - y * y / 2)
    v = y * sqrt(1 - x * x / 2)
    return u, v


sk = ob.shape_key_add(name="Basis")
ci = ob.shape_key_add(name="Cylinder")    
for v in me.vertices:
    ci.data[v.index].co.xy = squircle(*v.co.xy)

Note: Changing space would be more akin to changing Cartesian x, y, z to cylindrical r, theta, h where r is the radius, theta the angle around the axis and h the height of the cylinder. This wouldn't change the look.

Casting to Cylinder via modifier

Could instead add a cast modifier

enter image description here Result on subdivided default cube, radius set to sqrt(2)

Not sure the top is the result desired, to which would possibly require using a weighted vertex group for interior verts with cylinder axis aligned normals.

$\endgroup$
8
  • $\begingroup$ I never seemed to get the right orientation for the cylinder when I was playing with Cast on the weekend, even after trying every combination of the axes it seemed like it always laid the cylinder across my object and seemed to act as if a cylinder was being smashed into my object, rather than my object being expanded out into a cylinder. (Blender is really crying when doing all these operations too, ~10 seconds to change any parameter!) $\endgroup$
    – Hakanai
    Commented Aug 25, 2020 at 19:45
  • $\begingroup$ (The script seems like it might work but it will be my first time running a script that's not neatly packaged into a UI!) $\endgroup$
    – Hakanai
    Commented Aug 25, 2020 at 19:46
  • $\begingroup$ Nuts, I get a cryptic "ValueError: math domain error". I don't know python too well but from googling this seems to be something you get if you try to get sqrt of a negative number? So I guess my object doesn't lie within the unit box (although visually it actually does. so this is annoying. I think maybe the vertices have larger values and the overall object is scaled back down to size?) $\endgroup$
    – Hakanai
    Commented Aug 25, 2020 at 19:52
  • $\begingroup$ As noted need to make sure the cube is local dimensions 2 x 2 x 2, or adjust the 1 in formula to the "radius" of your cube. The math domain error is trying to find square root of negative number because coords are outside range (-1, 1) Apply scale to make it fit in 2 x 2 x 2 box (default cube) , then scale to whatever size. The script is using local coordinates, eg for def cube the corners are (1, 1, 1) to (-1, -1, -1) and combos of. $\endgroup$
    – batFINGER
    Commented Aug 25, 2020 at 19:56
  • $\begingroup$ Yeah I'm trying to figure out how the cube is bigger because as of right now it looks exactly like it extends from -1 ... 1. $\endgroup$
    – Hakanai
    Commented Aug 25, 2020 at 20:07
1
$\begingroup$

You can add a modifier Cast. By default it will deform your model into a sphere shape, but you can set the shape to a cylinder or cuboid.

You might want to plya with the axes and factor to get precisely Hat you want.

$\endgroup$
0
$\begingroup$

If you have the formula of a Schwarz-Christoffel mapping, you could write a simple script to do it, mapping vertex by vertex. But frankly, there are easier ways to do it, like using map projections. It is trivial to map a cube to sphere. Subdivide a cube several times and then apply Mesh > Transform > To Sphere. And most map projections are cylindrical projections.

$\endgroup$
2
  • $\begingroup$ IIRC Schwarz-Christoffel is non trivial. IMO most classical map projections map the surface of a sphere onto an open cylinder and then unfurl it flat for printing on a map. eg mercator or Equirectangular where the poles are singularities that are not mapped one to one, rather to the whole top and bottom edge of the map. ... and "frankly" would require mapping generated sphere vertex by vertex (in some form). $\endgroup$
    – batFINGER
    Commented Aug 25, 2020 at 17:22
  • $\begingroup$ To fill cylinder ends would require flattening above and below a certain latitude to form caps of cylinder. Somewhat akin to UV mapping here blender.stackexchange.com/a/185949/15543. Not sure it will produce a top similar to mapping shown in question, as it will require pole to converge to one vert. $\endgroup$
    – batFINGER
    Commented Aug 25, 2020 at 17:27

You must log in to answer this question.

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