Normalize @P with an SOP to get a sphere out of a box?

   1665   13   4
User Avatar
Member
143 posts
Joined: May 2017
Offline
Hey everyone,

is there a way to normalize a box with a SOP that results in a sphere? I'm not looking for a vex, expression or python solution, but something I can create directly using a sop. I need the whole thing to be a verb. Maybe there is a SOP directly for this - a quad based sphere?

Edited by viklc - May 9, 2023 10:03:38

Attachments:
box-to-sphere.gif (601.7 KB)

User Avatar
Member
396 posts
Joined: Nov. 2016
Offline
Not too sure how to interpolate outside of vex, but one way to spherify a box would be with the Attribute Noise Vector sop, by checking Noise along vector and having an equal min and vax value.



Edit: Here's a way. I'm renaming P to P_sphere in the attribute copy, and blending it in in Attribute Combine.

Edited by Tanto - May 9, 2023 10:59:48

Attachments:
Screenshot from 2023-05-09 10-11-45.png (863.6 KB)
Screenshot from 2023-05-09 10-58-15.png (32.6 KB)

User Avatar
Member
2041 posts
Joined: Sept. 2015
Offline
vik_lc
I'm not looking for a vex, expression or python solution, but something I can create directly using a sop.

Is there a reason you want it specifically as a 'SOP' (the vex example you provided) ?

Convert what you have into a digital asset, so you just have to place that asset(like a SOP) in your network?
User Avatar
Member
143 posts
Joined: May 2017
Offline
Hey Tanto,

that would be perfect, but unfortunately the Noise Sop attribute is not available as a verb - still an interesting solution to keep in mind, thanks!

Labs provides a Quad Based Sphere sop, but this again is not supported as a verb. Subdivide sop would be an option, but the result is not uniform, so the radius varies between 0-1.

So my current solution is the following:
Python SOP
node = hou.pwd()
geo = node.geometry()
# Set box verb.
sops = hou.sopNodeTypeCategory()
box = sops.nodeVerb("box")
box.setParms({"type": 1, "divrate": (8,8,8)})
box.execute(geo, [])

# Return a tuple of floats containing one attribute’s values for all the points.
pnt_comp = geo.pointFloatAttribValues("P")
# Number of points.
npnts = int(len(pnt_comp) / 3)
# Empty list for appending normalized values.
pnt_comp_normalized_list = []

# Run through all the points float components, put them into a vector, normalize 
# it and append the new component values into a list.
for i in range(npnts):
    vec = hou.Vector3()
    for j in range(3):
        vec[j] = pnt_comp[i * 3 + j]
    vec = vec.normalized()
    for j in range(3):
        pnt_comp_normalized_list.append(vec[j])

# Create a tuple from the list.        
pnt_comp_normalized = tuple(pnt_comp_normalized_list)
# Apply the normalized values.
geo.setPointFloatAttribValues("P", pnt_comp_normalized)

But I want to avoid running Python through individual points.


Hey BabaJ,

sorry I should have focused on Verbs in the title. To get a clear picture of what I'm working on is this: I am currently learning states and viewer handles, and would like to optimize the workflow or make it more accessible. Especially the concept of viewer handles is not easy to grasp, at least from my own experience. Handles are supposed to work independently of nodes, which in turn complicates the implementation of geometry and restricts it to verbs. The idea with Verbs is a fine one, namely perfomence and independence from Node / Sop geometry that can be easily loaded into a Drawable, for example. But as said, in the context with viewer handles you have no direct access to SOP geometry. (elovikov has an interesting solution here [www.sidefx.com]). However, this is not the purpose of viewer handles.

So I'm currently working on a complementary python lib to simplify the implementation of verbs. Drawable gatgets only support polygon geometry, which makes initializing verbs very annoying. You often have to adjust parameters individually, so that you can see anything at all. In addition they are not consistent. That's what I'm trying to solve. The library will provide new classes that will provide normalized and optimized verb geometry in no time. On the one hand you have basic primitives, an example:
box = verbs.Prim("box")
Done you have a box that works as a GatgetDrawable in Viewer Handle context. Another example would be an arrow:
Arrow = verbs.Arrow("settings").
And so on...

I am making good progress and everything is working. But I want the primitives to all be consistent. When I'm between a circle and a sphere, as in the following figure, I want the division to be consistent.

This is a parameter that works consistently for all the other primitives, but I'm not having success with the standard sphere - it would be doable with a quad-based sphere - And again, for performance reasons, I try not to go through all the points with Python.

I will present the first results here in the forum in a few days.
Edited by viklc - May 9, 2023 12:24:08

Attachments:
handle_editor.gif (317.2 KB)

User Avatar
Member
143 posts
Joined: May 2017
Offline
Hm, I didn't take a closer look at the Quad Sphere in terms of the point-to-point relation. The distances are the same for the box itself, but once the points are normalized, they are no longer uniform.

Spherical geometry seems to be a very interesting field - how each type of sphere has certain properties that others don't - although there is no sphere that has it all, you always have to compromise in some way.
source [docs.daz3d.com]

The only spherical shape that has the same point-to-point distance relation is the icosahedron, which is available in Houdini as a polygon sphere type. But this one doesn't have a uniform terminator, so it could lie on a plane.

I made this work with the Globe Sphere (polygon mesh). So the circle lies evenly on the points of the sphere in all axis orientations.
Edited by viklc - May 10, 2023 09:23:23

Attachments:
circle_sphere_match.gif (149.0 KB)
3D Primitives.png (165.4 KB)

User Avatar
Member
122 posts
Joined: June 2019
Offline
You can use compiled graphs in this context. Check the example, you just need Invoke Compiled Graph verb and the graph itself which is basically geometry. With that you can use any compilable networks and hdas.

You just need to bring geometry to the script, but you can even embed it in .py file as byte sequence as I did here: https://www.sidefx.com/forum/topic/86736/ [www.sidefx.com]

==

I've created once a "verbifier" for such a thing, but right now with invokable graphs it doesn't make much sense
https://github.com/igor-elovikov/hipie/blob/main/help/verbifier.md [github.com]

Attachments:
invoke.hiplc (246.1 KB)

User Avatar
Member
900 posts
Joined: Feb. 2016
Offline
elovikov
You can use compiled graphs in this context. Check the example, you just need Invoke Compiled Graph verb and the graph itself which is basically geometry. With that you can use any compilable networks and hdas.

You just need to bring geometry to the script, but you can even embed it in .py file as byte sequence as I did here: https://www.sidefx.com/forum/topic/86736/ [www.sidefx.com]

==

I've created once a "verbifier" for such a thing, but right now with invokable graphs it doesn't make much sense
https://github.com/igor-elovikov/hipie/blob/main/help/verbifier.md [github.com]


I'm not the op, but thanks a lot anyway!
that's a great showcase of more advanced stuff that I might need in the near future.
cheers
Edited by Andr - May 10, 2023 11:12:40
User Avatar
Member
900 posts
Joined: Feb. 2016
Offline
edit double
Edited by Andr - May 10, 2023 11:12:25
User Avatar
Member
143 posts
Joined: May 2017
Offline
elovikov
You can use compiled graphs in this context. Check the example, you just need Invoke Compiled Graph verb and the graph itself which is basically geometry. With that you can use any compilable networks and hdas.

You just need to bring geometry to the script, but you can even embed it in .py file as byte sequence as I did here: https://www.sidefx.com/forum/topic/86736/ [www.sidefx.com]

==

I've created once a "verbifier" for such a thing, but right now with invokable graphs it doesn't make much sense
https://github.com/igor-elovikov/hipie/blob/main/help/verbifier.md [github.com]

Oh man, that's really cool, thanks a lot!
I'll take a closer look, but I can already see the potential. This will certainly save some time.
User Avatar
Member
143 posts
Joined: May 2017
Offline
elovikov
Attachments:
invoke.hiplc (246.1 KB)

Thanks for the sample file, contains everything I need!
Nice to have you here!
User Avatar
Member
861 posts
Joined: Oct. 2008
Offline
Woah, what's this?

geo: hou.Geometry = node.geometry()
--
Jobless
User Avatar
Member
900 posts
Joined: Feb. 2016
Offline
Soothsayer
Woah, what's this?

geo: hou.Geometry = node.geometry()


I believe it just declares the datatype of the variable.
It's called "variable annotations"
Not necessary, but might be better for reviewing and understanding the code.


Also new to me, I'm watching this video about it
https://www.youtube.com/watch?v=QORvB-_mbZ0 [www.youtube.com]
User Avatar
Member
122 posts
Joined: June 2019
Offline
I actually used it here purely for vscode.
Because otherwise autocompletion won't work, if I don't annotate it just doesn't know what geo is.


I'm rarely writing in houdini itself, can't work without autocompletion

It's actually better to use them anyway and try to switch to "strict typing".

Also I've spotted the Py3.9 With Strict Types in this H20 feature https://youtu.be/_Wt41iCW7-s. [youtu.be] So I think Houdini is also moving in this direction, I wonder what is it

Attachments:
types.png (59.1 KB)

User Avatar
Member
143 posts
Joined: May 2017
Offline
Man the whole thing makes me rethink completely my intention, in a good way. It takes away so much tedious work, and it's still clean and fast.

Stash invoke opens up so many possibilities. You can basically completely generate geometry in VEX, cache it, and still keep it parametric. You could now create your own VEX library and call it with invokegraph anytime in Python with great performance.

Below is an example where I modify a box into a quad sphere with VEX, save it as stash geometry in a json, and then call it arbitrarily in Python. This is basically a summary from elovikov examples.

Thanks guys for sharing such knowledge here, nice place to be!

Image Not Found
Edited by viklc - May 11, 2023 12:38:12

Attachments:
invoke_quad_sphere_stash.hiplc (114.7 KB)

  • Quick Links