Python/Hscript Select Visible Geometry only

   349   6   0
User Avatar
Member
17 posts
Joined: April 2012
Offline
I want to select visible geometry only in an automated fashion. Thanks!

I am able to select the visible geometry in the viewport manually by enabling ‘Area Select Visible Geometry only’ and selecting on the scene.

I was wondering if it's possible to achieve this via script (HScript or Python). I know Maya has a script that does this so was hoping to find a similar option in Houdini too.
User Avatar
Member
410 posts
Joined: Dec. 2006
Online
scene_viewer = hou.ui.paneTabOfType(hou.paneTabType.SceneViewer)
scene_viewer.setPickingVisibleGeometry(True)
https://www.patreon.com/user?u=14076972 [www.patreon.com]
https://vimeo.com/user43923185 [vimeo.com]
https://gumroad.com/alexeyvanzhula [gumroad.com]
User Avatar
Member
17 posts
Joined: April 2012
Offline
Thanks for the input.

Unfortunatelly, I got that far and that is setting the toggle on only.

What I am after is a script to do the actual selection of the visible faces only.

This may not be entirely possible in Houdini yet, but it would be nice.
User Avatar
Member
410 posts
Joined: Dec. 2006
Online
ant_5555
Thanks for the input.

Unfortunatelly, I got that far and that is setting the toggle on only.

What I am after is a script to do the actual selection of the visible faces only.

This may not be entirely possible in Houdini yet, but it would be nice.

Shelf script:
scene_viewer = hou.ui.paneTabOfType(hou.paneTabType.SceneViewer)
pwd = scene_viewer.pwd()
if pwd.childTypeCategory() == hou.sopNodeTypeCategory():
    sop = pwd.displayNode()
    if sop is not None:
        sop = sop.createOutputNode('groupexpression')
        view_normal = hou.Vector3(0, 0, 1) * scene_viewer.curViewport().viewTransform().transposed().inverted()
        sop.parm('groupname1').set('viewprims')
        sop.parm('snippet1').set('dot(prim_normal(0, @elemnum, 0.5, 0.5), {%f, %f, %f}) > 0' % (view_normal[0], view_normal[1], view_normal[2]))
        sop.setCurrent(True, True)
        sop.setDisplayFlag(True)
        sop.setRenderFlag(True)
        sop.setHighlightFlag(True)
        scene_viewer.enterCurrentNodeState()
https://www.patreon.com/user?u=14076972 [www.patreon.com]
https://vimeo.com/user43923185 [vimeo.com]
https://gumroad.com/alexeyvanzhula [gumroad.com]
User Avatar
Member
17 posts
Joined: April 2012
Offline
Thanks again for your script. However, not quite there yet

I'm away from my computer right now so I can't quite test it so forgive me if I'm wrong, but if I look at your code… It seems to me you are just selecting front-facing faces, regardless of whether they are visible or occluded.

Again, my intent is to get visible primitives only. I want to make a script that has the same behaviour as enabling ‘Area Select Visible Geometry only’ and then manually selecting everything in the view.

This selects all visible faces, but ignores the occluded ones.
User Avatar
Member
21 posts
Joined: June 2006
Offline
hi Ant,
first off you need to choose a point of view (say, your camera position).
Then you need to cast rays from the cam position to every face on your geometry.
If the ray intersects the face you're casting the ray to it means that face is visible.

This is the code (drop it in a Primitive Wrangle):
Note that this works with poly objects only.

vector cam_pos = chv("point_of_view");
vector dir = 10000.0*normalize(v@P - cam_pos);
vector intP,intUV;
int pr = intersect(0, origin, dir, intP, intUV);
int visible = (pr==@primnum);
i@visible = visible;
v@Cd = set(i@visible,0,1-i@visible); // just a color feedback

p.s.
the number 10000.0 is just a number large enough to cover the distance from the camera to your object , this is because the VEX command intersect uses the lenght of the vector ‘dir’ as max intersection distance.

P.S.
I just realized you wanted a python/hscript version. Uhpss .. Well this is the faster version of that
Edited by mrWolf - April 23, 2019 19:15:44
Alessandro Pepe
http://www.alessandropepe.com [www.alessandropepe.com]
http://pepefx.blogspot.com [pepefx.blogspot.com]
User Avatar
Member
17 posts
Joined: April 2012
Offline
Hi Mr.Wolf,

Thanks for the response. That was my very first approach to this solution, it's pretty good but fails when v@P of the primitive is occluded by another primitive (and all you see is a corner).

Essentially, I am trying to clean my geometry to delete faces that are not visible.

Even if wrangle is faster than python, intersect can become quite expensive when dealing with millions of polygons, and also, intersect sometimes fails to retrieve the right information… Rarely, but obvious when dealing with so many prims.

The best approach I have so far involves a procedural system that uses renders and cops to check visible geometry. However, bottlenecks at each render…

But since I can manually “click and drag” a box that selects all visible geometry… I'm surprised there isn's already a function that does that automatically as it would make this so much faster.

Thanks all for the feedback though,
  • Quick Links