Quantcast
Channel: Scripting - McNeel Forum
Viewing all articles
Browse latest Browse all 5877

SetPtMulti (Multi version of SetPt)

$
0
0

@RIL wrote:

OK, so I made my first PythonScript attempting to extend Rhino's std SetPt command.

The idea is to be able to set multiple points at once using a another object (Curve or Surface) as a "template" for where to move the Control Point positions. Each Point to be moved/pulled needs a matching "template" point to guide it's target position.

The command allows for window selecting of Control Points.

In its first version it is recommended to select entire rows of Control Points, not only individual Points (use SetPt for that). The current version of the script tends to swap directions if not entire point rows are selected. The number of template target points must not be less than the pull points.

SetPtMulti can set 1, 2 or 3 directions (just like the original SetPt command) which then are applied for each Pull-Target pair.

SetPtMulti has been briefly tested to support matches of the following object types :

  • Curve -> Curve control points
  • Curve -> Surface control points
  • Surface to Surface control points
  • Surface to Curve control points

Video Clip
Below a 1.2 min video clip demonstrating how the command is used in its first version. If you have any suggestions, or want to contribute to extend and enhance the script, just let me know.

Video clip :
https://drive.google.com/file/d/0B2OlFpI0gNEGTWNsTVdJSFdTblk/view?usp=sharing

The Script (R0.9). Let the code review begin! ( :sweat_smile: ):

import rhinoscriptsyntax as rs

# ------------------------------------------------------------------
# Rolf Lampa, 2016 Rev 0.9
# SetPtMulti is intended as an extended version of Rhino's std SetPt
# command.  It sets multiple points to corresponding target points in
# pairs.
# Command line options to set: X, Y, Z, All, or Cancel
# -------------------------------------------------------------------

def SetPtMulti():

    def ExitProc(SelObj1=None, SelObj2=None):
        if SelObj1:
            rs.EnableObjectGrips(SelObj1, False)   # Hide Control points
        if SelObj2:
            rs.EnableObjectGrips(SelObj2, False)   # Hide Control points
        #rs.GetObjects()     # clear selection

    # ------------------------------------------------------------------
    # MAIN
    # ------------------------------------------------------------------
    # CONST
    X = 0
    Y = 1
    Z = 2
    ALL = 3
    CANCEL = 4

    # Select Object to Modify
    moveObj = rs.GetObject("Select object to Move", filter=4+8, select=True) # Curve, Surface
    if not moveObj:
        return
    rs.EnableObjectGrips(moveObj)   # Show Control points

    moveObjIsSurface = rs.IsSurface(moveObj)

    # TARGET
    targetObj = rs.GetObject("Select Target object", filter=4+8, select=True) # Curve, Surface
    if not targetObj:
         ExitProc(moveObj, None)
         return

    targetObjIsSurface = rs.IsSurface(targetObj)

    # Get POINTS to Move
    msg1 = "Select Points to Pull :"
    unsorted = rs.GetObjectGrips(message=msg1, select=True)
    if not unsorted:
        ExitProc(moveObj, None)
        return
    # SORT
    unsorted.sort(key = lambda g : g[1])
    movePoints = unsorted

    # Target POINTS
    msg1="Select target Points :"
    rs.EnableObjectGrips(targetObj)   # Show Control points
    unsorted = rs.GetObjectGrips(message=msg1, select=True)
    if not unsorted:
        ExitProc(moveObj, None)
        return
    # SORT
    unsorted.sort(key = lambda g : g[1])
    trgPoints = unsorted
    if not trgPoints:
        return

    # Points to move (grips) must be less or equal to target points.
    if len(movePoints) > len(trgPoints):
        rs.MessageBox("Number of points to move must be less or equal to target points!", buttons=16, title="Warning")
        return

    # DIRECTIONS select :
    uvn_params = ("X", "No", "Yes"), ("Y", "No", "Yes"), ("Z", "No", "Yes"), ("All", "No", "Yes"), ("Cancel", "No", "Yes")
    uvn_directions = rs.GetBoolean("Directions to modify:", uvn_params, (False, False, False, False, False) )
    if uvn_directions[CANCEL]:
        ExitProc(moveObj, targetObj)
        return
    elif (not (uvn_directions[X] or uvn_directions[Y] or uvn_directions[Z])
        and (not uvn_directions[ALL])):
        rs.MessageBox("No directions was selected! Try again.", buttons=64, title="Ops!")
        ExitProc(moveObj, targetObj)
        return

    # Set directions, individually (x,y,z) or "all" :
    is_valid_options = False
    if uvn_directions[ALL]:
        uvn_directions[X] = True
        uvn_directions[Y] = True
        uvn_directions[Z] = True
        is_valid_options = True
    else:
        for val in uvn_directions:
            if not is_valid_options and val:
                is_valid_options = True
                break

    if not is_valid_options:
        rs.MessageBox("No directions was selected! Try again.", buttons=64, title="Ops!")
        return

    # Move any pairs of points between any object type
    # (surface to curve, curve to curve,
    #  curve to surface or surface to surface

    #rs.EnableRedraw(False)             # Lock screen
    i = 0
    for grip in movePoints:
        # Get points
        obj, ix, movePt = grip
        obj, trgIx, trgPt = trgPoints[i] # trgPoints[i][2]

        # Copy target's pts to the object to be moved
        if uvn_directions[X]:
            movePt[X] = trgPt[X]
        if uvn_directions[Y]:
            movePt[Y] = trgPt[Y]
        if uvn_directions[Z]:
            movePt[Z] = trgPt[Z]

        if moveObjIsSurface:
            rs.ObjectGripLocation(moveObj, ix, movePt)
        else:
            rs.ObjectGripLocation(moveObj, ix, movePt)
        # next movePt
        i += 1

    ExitProc(moveObj, targetObj)
    rs.EnableRedraw(True)

SetPtMulti()

// Rolf

Posts: 1

Participants: 1

Read full topic


Viewing all articles
Browse latest Browse all 5877

Trending Articles