"Solid" clipping plane

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: "Solid" clipping plane

Post by looo »

again some references:

coin adds the clipPlane here:
https://github.com/looooo/coin3d/blob/m ... p#L131L144

the plane gets removed when this function is called:
https://github.com/looooo/coin3d/blob/m ... pp#L87L100

The easiest way to implement the caping is to:
1. copy SoClipPlane.h, SoClipPlaneElement.h, SoGLClipPlaneElement.h and the coresponding cpp files.
2. rename Clip to Cap
3. add the gl-stuff for rendering the the cap to SoGLClipPlaneElement::addToElt

Maybe it would be also possible to implement by SubClassing a SoSeparator. But there is the need to get the traversal-end event (pop) and I have no idea how to get this end-event...
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: "Solid" clipping plane

Post by looo »

using a SoCallback works also in FreeCAD: (still only python code + some changes in pivy to make the SoCallback work with freecad)
gear_cap.png
gear_cap.png (15.15 KiB) Viewed 3492 times
but selection makes some problems...
selection_problem.png
selection_problem.png (19.17 KiB) Viewed 3492 times
Is there a way to disable the selection for some renderBelowPath calls?
User avatar
pablogil
Posts: 881
Joined: Wed Nov 26, 2014 3:19 pm
Location: Badajoz (Spain)
Contact:

Re: "Solid" clipping plane

Post by pablogil »

Very interesting! It's almost done

Cheers
Dark and Light stylesheets v2.0 to theme your FreeCAD UI, more information here
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: "Solid" clipping plane

Post by looo »

Yes, after playing with the stencil-buffer another time, the problem with the selection is gone.
Currently the algorithm has some problems with the sketcher (crash) and there are still some small artifacts with lines... Also I do not know how to draw the capping-plane. Somehow the size has to be specified.

Code: Select all

import sys
from PySide import QtGui
from pivy import coin
from OpenGL.GL import *

handled=False

class CapPlane():
    def __init__(self, node):
        self.node = node
    def stencilBuffer(self, action):
        glEnable(GL_CLIP_PLANE0)
        glEnable(GL_STENCIL_TEST);
        glClear(GL_STENCIL_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE)
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
        # Draw Front faces and decrease stencil-buffer
        # where the front_face is drawn
        glStencilFunc(GL_ALWAYS, 0, 0);

        glDisable(GL_DEPTH_TEST)
        glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT)
        glCullFace(GL_FRONT)
        self.node.GLRenderBelowPath(action)
        # draw the back_face to the stencil-buffer
        # decrease the stencil buffer where the back-face is drawn
        glCullFace(GL_BACK)
        glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT)
        self.node.GLRenderBelowPath(action)
        # Draw a quad aligned with the stencil plane,
        # but set the stencil test to reject pixels unless the stencil is set.
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
        glEnable(GL_DEPTH_TEST)
        glDisable(GL_CLIP_PLANE0)
        glStencilFunc(GL_NOTEQUAL, 2, ~0)
        glStencilFunc(GL_NOTEQUAL, 0, ~0)
        glColor3f(0.8, 0.8, 0.8)
        glDisable(GL_CULL_FACE)
        glDisable(GL_LIGHTING)
        glBegin(GL_QUADS)
        glVertex3fv([-10000,-10000, 3])
        glVertex3fv([ 10000,-10000, 3])
        glVertex3fv([ 10000, 10000, 3])
        glVertex3fv([-10000, 10000, 3])
        glEnd()
        glEnable(GL_LIGHTING)
        glDisable(GL_STENCIL_TEST)
        glEnable(GL_CLIP_PLANE0)
        glClear(GL_STENCIL_BUFFER_BIT)
        glDisable(GL_CULL_FACE)

def myCallbackRoutine(cap, action):
    global handled
    if not action.isOfType(coin.SoGLRenderAction.getClassTypeId()):
        return
    if not handled:
        handled = True
        cap.stencilBuffer(coin.SoGLRenderAction.constructFromAction(action))
        handled = False

view = Gui.ActiveDocument.ActiveView
sg = view.getSceneGraph()
myCallback = coin.SoCallback()
cap = CapPlane(sg)
myCallback.setCallback(myCallbackRoutine, cap)

plane = coin.SbPlane(coin.SbVec3f(0,0,1), coin.SbVec3f(0,0,3))
clip = coin.SoClipPlane()
clip.plane = plane
sg.insertChild(clip, 2)
sg.insertChild(myCallback, 3)
selection_works.png
selection_works.png (28.34 KiB) Viewed 3438 times
HoWil
Veteran
Posts: 1279
Joined: Sun Jun 14, 2015 7:31 pm
Location: Austria

Re: "Solid" clipping plane

Post by HoWil »

Looks nice,
Is this possible without blocking the Task-panel as the original clipping tool does?
This could be very usefull for FEM-wb for selecting inner solids and faces.
Please see also https://forum.freecadweb.org/viewtopic. ... 50#p151950 to get an impression what I need sometimes in FEM-wb.
BR,
HoWil
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: "Solid" clipping plane

Post by looo »

HoWill wrote:Is this possible without blocking the Task-panel as the original clipping tool does?
Maybe the SoClipPlanManip node could be useful. I think drawing the cap is not that important for this task.

Code: Select all

from pivy import coin
sg = Gui.ActiveDocument.ActiveView.getSceneGraph()
clip_plane = coin.SoClipPlaneManip()
sg.insertChild(clip_plane, 0)
# sg.removeChild(clip_plane, 0)
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: "Solid" clipping plane

Post by yorik »

very interesting progresses looo! Didn't think there was something liek that available at coin level already...
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: "Solid" clipping plane

Post by looo »

yorik wrote:very interesting progresses looo! Didn't think there was something liek that available at coin level already...
it isn't yet available with coin. My code implement the capping at opengl-level. But it is very nice that this is possible from python...

I have done some further tests, but didn't find a way to remove the artifacts... I think this isn't a problem of the stencil-buffer algorithm. But maybe there is a way to get rid of the artifacts (use the shaded render mode for the stencil renderings)

I also had a look how the clipping-plane is implemented in osg. And I think there approach (every separator can enable a clipping-plane) is more suited for CAD.

Does FreeCAD already use a subclass of a SoSeparator for shapes? If not I would suggest to do so and implement the "CAD-clipping" at the separator-level. The idea is to have clipping planes defined in a separator somewhere near the root-separator and CAD-Separators to implement the glEnable(GL_CLIP_PLANE0) and glDisable(GL_CLIP_PLANE0)...
The CAD-Sparator then gets two bool-value for the clip-type shell/solid, on/off. In SoSeparator::GLRenderInPath the planes get enabled and regarding the clip-style the stencil-buffer-algorythm will be used or not.
In SoSeparator::GLRenderOffPath the plane gets disabled. Maybe a SoAction can be used to enable/disable the clip-planes for all separator.

questions:
1: If I implement this in FreeCAD, is it possible to have this SoSeparator-subclass available from python, and use it like a pivy-node?
2: Can I switch the rendermode for the two stencil-buffer-renderings? And how to achieve that? (It seems the rendermode with only polygons, doesn't show any artifacts.)
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: "Solid" clipping plane

Post by wmayer »

1: If I implement this in FreeCAD, is it possible to have this SoSeparator-subclass available from python, and use it like a pivy-node?

Code: Select all

from pivy import coin
type=coin.SoType.fromName("SoFCSelection") # FreeCAD specific type
type.isBad() # => 0, i.e. OK
node=type.createInstance()
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: "Solid" clipping plane

Post by looo »

thanks, this is perfect.

Tested the python code posted above in windows, and there no artifacts are visible... but somehow the line picking is affected.
Post Reply