Custom History plugin, Possible?


#1

Hi, is it possible to make a custom command/plugin that utilizes the history setting so it autoupdates on adjustments?


#2

I have only written history commands in C++, but it appears it can be done using C Sharp, and it is much easier.


#3

Hey thanks, but that seems to be a bit above my level…
I’ll investigate another way first :smiley:


#4

At what level are you comfortable? Is it the language that is the issue?

What are you trying to add history support to? Wouldn’t grasshopper work just as well?


#5

Dang, those are hard questions…
My level is complex-novice meaning I get some complex stuff accomplished with my novice skills… but I am no programmer so i often end up in deep water.
My goal is to modify a mesh and updating another mesh at the same time.
Grasshopper is not my preferred way to go, as it will be used by users who has no Rhino experience, and they should not need it either, so a I think a plugin with a toolbar is a better UX.


(Dale Fugier) #6

Hi @Holo,

The above sample referenced by @mnewberg is also available in a RhinoCommon, C# flavor it this any help to you.

https://github.com/mcneel/rhino-developer-samples/blob/6/cpp/SampleCommands/cmdSampleHistory.cpp

– Dale


#7

Another way to handle it is via an event watcher, below is a simple command and event watcher. If you add a mesh in the boudingbox (minx:-50,miny:-25,minz:50, maxx:50, maxy:25, maxz:50) it automatically splops it on a hidden surface around the points (0, 50, 0). Having history work in this method is a really fun way to draw/array geometry ontop of surfaces.

https://github.com/matthewnewberg/MiniRhino3dUtils/blob/master/EventWatcherMeshUpdate/EventWatcherMeshUpdate/EventWatcherMeshUpdateCommand.cs


#8

Oh man…as if Python isn’t difficult enough… :smiley:
I think we need to start simpler and run it as a command instead of enabling history right now.

As an example: Is it possible make a script where I select a mesh and have it turn on the editpoints so I can manipulate it while it runs (as a simple example) the command “LineThroughPoints” on all the vertices whenever a vertex is modified?
(Or that it draws the mesh face centers and updates these whenever a point is modified?) And then stop the command when I hit Enter or right click?

Having the ability to in realtime update a boundingbox while the user is able to modifying a mesh’ vertices with a gumball would also be right up my ally… I don’t know if that’s even possible in a quite simple way though. (Simple is key as I will probably need to maintain and update the code in the following years, but not often, so in six months time my mind will have to be able to pick up where I left… (and THAT challenge I have experienced all ready on the (for me) complex scripts I have made in the past)

So I think doing it through a command is easier for me to handle… maybe… :smiley:


#9

Thanks for the effort Matthew,I’ll see if I can convert that to Python so I can give it a try to modify it to my need, but my head hurts all ready :smiley:


#10

Hi @dale
My intention was to make a script where the user can manipulate the vertices with the gumball and press enter when done, but this might not be possible, so history might be better and I am willing to put down the hours to see if I can master it.

Does this mean that I can use it in Python? Introducing a new language isn’t really an option at this stage.
(I ask before I try to convert the 180 lines so I don’t waste too much time, but I’ll try if you think it’s possible)

Thanks


#11

@Holo

I know a bit of Python and tried to rewrite it, but it appears scriptcontext.doc.AddRhinoObject is broken.

@stevebaer Do you know of a way to use AddRhinoObject from Python?


(Steve Baer) #12

RhinoCommon in general does not allow you to directly create new RhinoObject instances. AddRhinoObject is only for custom objects.

History won’t work with python as Rhino needs a persistent command Id that it needs to know to call a virtual function on when update history needs to occur


#13

Thanks a lot for trying Matthew!


#14

Do you have any suggestions for an alternative path? I think tackling C# is out of my league and that makes me hesitate as I will have to evolve and bug track the thing down the road.


#15

Your requests are not difficult in C Sharp. I was interested myself in whether things like this could be done in Python or not. It looks like Python is great for writing small scripts but is incapable of accessing the more in-depth features in Rhino.

MeshLineThroughPts (using Rhino History):

miniMeshFaceCenters: (using EventWatcher)

MeshBoundingBox: (using Rhino History)

The final rhp is here:


#16

Hi Steve, I see. Also History doesn’t update in realtime, so I am not 100% sure it is the right way to go for me.

So one thing I need to know is: Is it possible to manipulate a vertex with the gumball while a python script is running? I made a mesh vertex manipulation script that draws XYZ lines at the vertex point for snapping and lets the user manipulate points until satisfied, but it is not as smooth as using the Gumball. (I will of course now work on making the mesh update realtime, and then move on to coding the replacment of that mesh with another one)

# mesh vertex manipulation WIP
# by Holo 2017

import rhinoscriptsyntax as rs
import scriptcontext as sc

dblLINE=10 # variable for the XYZ lines

# get mesh for manipulation
mesh_id=rs.GetObject("Select mesh to vertex edit",32,preselect=True)
if mesh_id:
    # make a virtual mesh
    mesh_obj = rs.coercemesh(mesh_id)
    vertices = mesh_obj.Vertices
    
    #turn on grips (controlpoints) if they are off
    if not rs.ObjectGripsOn (mesh_id)==True:
        rs.EnableObjectGrips( mesh_id )
    
    # Continue to SELCT point for manipulation until enter is pressed
    while True:
        grip = rs.GetObjectGrip("Select a vertex to move", select=True)
        if grip:
            
            #Continue to manipulate THAT POINT until enter is pressed
            while True:
                
                # the "grip-list" contains the vertex identifier as list item nr2
                index=grip[1]
                startPt=vertices[ index ]
                
                # Add X Y Z Lines for snapping
                # as gumball replacement
                def addLines(startPt):
                    #Add XYZ lines
                    lines=[]
                    lines.append( rs.AddLine([startPt.X-dblLINE,startPt.Y,startPt.Z] , [startPt.X+dblLINE,startPt.Y,startPt.Z] ) )
                    rs.ObjectColor(lines[0], (0,255,0) )
                    lines.append( rs.AddLine([startPt.X,startPt.Y-dblLINE,startPt.Z] , [startPt.X,startPt.Y+dblLINE,startPt.Z] ) )
                    rs.ObjectColor(lines[1], (255,0,0) )
                    lines.append( rs.AddLine([startPt.X,startPt.Y,startPt.Z-dblLINE] , [startPt.X,startPt.Y,startPt.Z+dblLINE] ) )
                    rs.ObjectColor(lines[2], (0,0,255) )
                    return lines
                lines=addLines(startPt)
                
                # get new position for the vertex
                newVertex=rs.GetPoint("New position", base_point=startPt, in_plane=True)
                #delete the XYZ lines
                rs.DeleteObjects(lines)
                
                #update mesh or go back to select point
                if newVertex:
                    vertices = mesh_obj.Vertices
                    vertices.SetVertex(index,newVertex)
                    # clear up vertex normals
                    mesh_obj.Normals.Clear()
                    mesh_obj.FaceNormals.Clear()
                    
                    #replace mesh
                    sc.doc.Objects.Replace(mesh_id,mesh_obj)
                
                else:
                    # no new destination so user is done manipulating that point
                    # so break while-True loop
                    break
        
        else:
            # user is done manipulating the mesh 
            # so turn off controlpoints and break while-True loop
            rs.EnableObjectGrips (mesh_id, enable=False)
            break
            

#17

Hi @dale I am getting results in Python and have managed to make a conduit that shows the “original” mesh in wireframe and my vertex-close sub-d solution in shaded. But for some reason the conduit is clipped both close and far (only close clipping shown here) so how can I control that? Is there a near clipping setting? Or is it a bug?

Also if I close the Rhino file and open a new one then the script stops working, or the display conduit as it doesn’t draw the meshes. Can I clear that out in a way?


(Steve Baer) #18

you need to tell the display pipeline about the new bounds that you want the camera to work with.
http://developer.rhino3d.com/api/RhinoCommonWin/html/M_Rhino_Display_DisplayConduit_CalculateBoundingBox.htm


(Steve Baer) #19

Our SDK access for the gumball isn’t very intuitive. I know @DavidRutten took a crack at making it easier to use a while ago and does have gumball manipulation in GH because of this. David, did we ever end up with some easy to use gumball routines in RhinoCommon?


#20

Ah… so THAT is what “bounding box” refer to in that context. That makes sense. Thanks, I’ll try it out!