Modify Clipping plane position in python


(Nico de Meester) #1

Is there a possibility in the python editor to modify the clipping plane position just by changing the .Plane.Origin.X value? (See picture below)


#2

@Nico_de_Meester, i guess you need to re-create the clipping plane like below:

def SetClippingPlaneOrigin():
    
    cp_id = rs.GetObject("Clipping plane", rs.filter.clippingplane, True, True)
    if not cp_id: return
    
    origin = rs.GetPoint("New clipping plane origin")
    if not origin: return
    
    cp_obj = rs.coercerhinoobject(cp_id, True, True)
    rc,x,y = cp_obj.ClippingPlaneGeometry.GetSurfaceSize()
    vp_ids = cp_obj.ClippingPlaneGeometry.ViewportIds()
    cplane = cp_obj.ClippingPlaneGeometry.Plane
    
    cplane.Origin = origin
    cplane.Translate(cplane.XAxis * x * -0.5)
    cplane.Translate(cplane.YAxis * y * -0.5)
    attr = cp_obj.Attributes
    
    scriptcontext.doc.Objects.AddClippingPlane(cplane, x, y, vp_ids, attr)
    scriptcontext.doc.Objects.Delete(cp_id, True)
    scriptcontext.doc.Views.Redraw()
    
SetClippingPlaneOrigin()

_
c.


(Nico de Meester) #3

Hi Clement,

Thanks for your replay. I learned of lot from this code.

I now see that you can add or remove the clipping views by adding or removing them from the viewport list.
Also that its possible to add all the attributes at ones. That is nice.

What I also see is that you delete the original clipping plane and add a modified one to the document.
Is that the way to operate? Or is it also possible to modify the existing clipping plane and update it.

In the code below I had some problems to manipulate the vp_ids list. So I create another list to handle the view ids. Is there a better way to acces this list. Or to convert them to a normal list.

import rhinoscriptsyntax as rs
import scriptcontext
import Rhino

def MoveObjects(object_ids, translation):
    translation = rs.coerce3dvector(translation, True)
    xf = Rhino.Geometry.Transform.Translation(translation)
    rc = TransformObjects(object_ids, xf)
    return rc

def ClippingPlane():
    plane=rs.PlaneFromNormal([0,0,0],[0,0,1])
    cp_id=rs.AddClippingPlane(plane,1000,1000,["Top","Front","Right"])
    rs.ObjectLayer(cp_id,"ClippingPlane")
    rs.ObjectName(cp_id,"Test 1")
    rs.SetUserText(cp_id,"ClippingSide","Left")
    CPG=rs.coercegeometry(cp_id)
    X=2000
    SetClippingPlaneOrigin(cp_id,X)
    return

def SetClippingPlaneOrigin(cp_id,x):
    
    if not cp_id: return
    origin=rs.coerce3dpoint((x,0,0))
    if not origin: return
    
    cp_obj = rs.coercerhinoobject(cp_id, True, True)
    rc,x,y = cp_obj.ClippingPlaneGeometry.GetSurfaceSize()
    cv_ID=scriptcontext.doc.Views.ActiveView.ActiveViewportID
    vp_ids = cp_obj.ClippingPlaneGeometry.ViewportIds()
    vplist=[]
    for vp in vp_ids:
        if vp<>cv_ID:
            vplist.append(vp)
    cplane = cp_obj.ClippingPlaneGeometry.Plane
    cplane.Origin = origin
    cplane.Translate(cplane.XAxis * x * -0.5)
    cplane.Translate(cplane.YAxis * y * -0.5)
    attr = cp_obj.Attributes
    
    scriptcontext.doc.Objects.AddClippingPlane(cplane, x, y, vplist, attr)
    #scriptcontext.doc.Objects.AddClippingPlane(cplane, x, y, vp_ids, attr)
    #scriptcontext.doc.Objects.Delete(cp_id, True)
    scriptcontext.doc.Views.Redraw()
    
if __name__ == "__main__":
    ClippingPlane()
    viewname=scriptcontext.doc.Views.ActiveView.ActiveViewportID
    print rs.coerceguid(viewname)

(Nico de Meester) #4

Hi Clement,

I still have some problems with the clippingplane. I try to make some kind of clipping box like shown in the picture. I use the ETO forms for it. It works.

def ClippingPanel():
    dialog = ClippingDialog();
    #dialog.ShowModal(Rhino.UI.RhinoEtoApp.MainWindow)
    Rhino.UI.EtoExtensions.ShowSemiModal(dialog, Rhino.RhinoDoc.ActiveDoc, Rhino.UI.RhinoEtoApp.MainWindow)
    return

I first used dialog.ShowModal(Rhino.UI.RhinoEtoApp.MainWindow) option to start the panel. But this gave me the limitation that I couldn’t rotate my ship when the macro/panel was running.

So I changed to Rhino.UI.EtoExtensions.ShowSemiModal(dialog, Rhino.RhinoDoc.ActiveDoc, Rhino.UI.RhinoEtoApp.MainWindow) now I could rotate but when I select one of the check boxs the macro stoped. It has to do with The rs.Command( ‘_enableclippingplane _selid ‘+str(objs[0])+’ _enter’) rows.
When I put an # in front of it it works.

def ClippingPlaneOnOff(name,state=True):
    layername='ClippingPlane'
    objs=rs.ObjectsByName(name)
    rs.LayerVisible(layername,True)
    if objs:
        if state:
            #string='_enableclippingplane _selid '+str(objs[0])+' _enter'
            #rs.Command(string)
            print ""
        else:
            print ""
            #rs.Command("_disableclippingplane _selid "+str(objs[0])+ " _enter")
    rs.LayerVisible(layername,False)
    return
def ClippingPanel():
    dialog = ClippingDialog();
    #dialog.ShowModal(Rhino.UI.RhinoEtoApp.MainWindow)
    Rhino.UI.EtoExtensions.ShowSemiModal(dialog, Rhino.RhinoDoc.ActiveDoc, Rhino.UI.RhinoEtoApp.MainWindow)
    return

I am now searching for the option that to create the Clipping plane and afterwards enable or disable it for my current view. Without using the rs.Command option. Is there a rhino common solution available?

image


#5

Hi Nico, i’ve tried to modify the clipping plane in place using Rhino 5 but it did not work as i expected using Commitchanges(). Also i tried to replace the old clipping plane with the new one using scriptcontext.doc.Objects.Replace so the ID does not change, but it looks like this is not supported yet for clipping planes.

It is an array according to the help. To convert it in one go you could try below:

vp_ids = list(cp_obj.ClippingPlaneGeometry.ViewportIds())

I can only guess without the full code example. Maybe this happens because when you add the new clipping plane, it’s ID changes so the dialog does not find it ?
_
c.