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
    Aug 25 '20 at 11:04
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
    Aug 25 '20 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
    Aug 25 '20 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
    Aug 25 '20 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
    Aug 25 '20 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
    Aug 25 '20 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
    Aug 25 '20 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
    Aug 25 '20 at 17:27

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.