4
$\begingroup$

I have a function like $f(x,y,z)=\text{constant}$. It is not straightforward to solve $z$ as a function of $x$, $y$, and $\text{constant}$ analytically. So, I want to choose a Constant value, draw that isosurface, and create a mesh on the surface.

1) is there any way to draw a function like $f(x,y,z)=\text{constant}$ without solving it?

2) If I want to set a range for all $x$, $y$, and $z$, how can I do this?

Thanks in advance for your reply and comments.

Cheers

$\endgroup$
  • $\begingroup$ Would it be more straightforward to convert the f(x, y, z)=constant to a set of three parametric equations, such that x=f(u, v), y=g(u, v) and z=h(u, v)? The Add Mesh: Extra Objects addon (comes bundled with Blender, but not enabled by default, IIRC), has (among other things) functions for generating meshes from both a set of parametric equations and from z=f(x, y). $\endgroup$ – Duane Dibbley May 14 '17 at 0:20
  • $\begingroup$ Hi Duane, thanks for your comment. I tried that as in here: blender.stackexchange.com/questions/74410/… I have tried parametric equations but it would be just x=u , y=v, and z=f(u,v). It will again requires the equation to be solved. Besides, I could not set any range for z in this case as it will be determined by the range of u and v for sure. $\endgroup$ – Mohsen May 15 '17 at 1:41
4
$\begingroup$

The following is a workaround rather than a complete solution. It doesn't answer your actual question, in that it doesn't generate a mesh representing the equation, thus you can't use image textures or do more elaborate things, like sculpting or rigging. It renders a visual representation of the equation, by using volumetric shading and some math nodes. Moreover, it's Cycles specific. What it does do, is work well with any implicit equation of three variables, as long as it uses functions that exist in Cycles math nodes.

So, how to do it...
Add a cube, which will serve as the bounding box (ShiftA followed by M followed by C or Add -> Mesh -> Cube).
Press N to open the properties panel, unless it's already open, and change the values for Dimension to the proper values, and apply the scale (CtrlA followed by S or Object -> Apply -> Scale). If for example you want to cover the range (-0.5, -0.5, -0.5) to (1.5, 1.5, 1.5) all dimension values should be set to 2.000, and if you want to cover the range (-1, -2.5, 0) to (5, 5, 5), the dimensions should be x = 6.000, y = 7.500, z = 5.000.

enter image description here

Now the box has the correct dimensions, but its origin is at its centre. With the above examples, the ranges will now be (-1, -1, -1) to (1, 1, 1) and (-3, -3.75, -2.5) to (3, 3.75, 2.5) respectively.
To remedy this, Tab into edit mode, and move the box along each axis, until it covers the range you need. Press G followed by the axis along which to move it, followed by the amount by which to move it, followed by Enter, for example G followed by X followed by Numpad 1 followed by Enter to move it by 1 along the x axis. For the above two examples, you need to move it by (0.5, 0.5, 0.5) and (2, 5, 2.5) respectively. When you're done, Tab back to object mode.

At this point, it's perfectly ok to move, rotate and scale the box, as long as you do so in object mode and don't apply any transformations. Also keep in mind that scaling is a bit special: unless you scale equally along all three axes, you will end up with different step size along the axes. This may be good or bad, and the decision is yours to make.

Open up the compositor, and make sure the shader editor is active and that Use Nodes is checked (the purple rectangles in the image below). If there is a button named New, click it, to create a new material.

enter image description here
Click the image to see a larger version

The nodes above corresponds to the equation sin(x)+sin(y)+cos(z)=1, which is the one you ask about in Creating mesh on a surface with two variables.

The nodes in the red rectangle give the coordinates with (0, 0, 0) at the object's origin. It's similar to using Object coordinates of the Texture Coordinate node, however the object coordinates places (0, 0, 0) at the centre of the bounding box, which isn't what we want.

The Separate XYZ node (the blue rectangle) does what its name suggests.

The nodes in the yellow rectangle are the left side of the equation.

The nodes in the green rectangle are the right side of the equation. This probably requires some explanation. If you simply use the Less Than 1.000 you will get everything inside the volume. To simulate a surface with a slight thickness, I subtract everything below some value that is less than 1 (0.9 in the image). The closer you set this to 1, the more it will look like it's infinitely thin, but the higher you will have to set the density to make it appear opaque.

The multiply node controls the density. The higher you set this, the more it will look like an opaque surface.

The Volume Absorption and the Volume Scatter are the shaders at work here, and the Add Shader combines those. You need not use absorption and scatter exactly like this, and you may use Mix Node instead of add, if you prefer. Just to remember to use volumetric nodes, and connect to the Volume socket of the Material Output node. The usable shaders for volumetric shading are Volume Absorption, Volume Scatter and Emission.

The Texture Coordinate connected to the Color sockets of the shaders, just maps the shading coordinates to a colour. Red along the X axis, green along the Y axis and blue along the Z axis.

Here's the result:

enter image description here

And here's an example .blend (it's not exactly identical to the example, but the concept is the same):

$\endgroup$
1
$\begingroup$

This might match the Marching Cubes algorithm.

https://github.com/mutantbob/blender-marching-cubes

https://en.wikipedia.org/wiki/Marching_cubes

I am not including the source code because it is >500 lines long

$\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.