Create similar?

Hello!
Is there some kind of ‘create similar’ command (á la Revit)?
You know, select a line > CS > create another line. Select an annotation > CS > create another…
Makes sense only when there’s one thing selected (or the first in the selection is taken).
Thanks!
Best regards

How would this differ from the Copy command in Rhino?

Create similar in Revit leverages the fact that most everything In Revit is object orientated.
Revit also has what are called system families(Family = block); essentially system based dynamic blocks (with lots of complexity/functionality) that ship out of the box (and in fact can’t be purged…) and are a core part in the building design workflow.

Selecting a family(block), system family, line, detail item, text note, etc and then using the create similar button/shortcut will begin the object creation dialogue for that item type.

Ie. and I’m dipping back into cad/rhino-esque analogies here; if you had a dynamic block that started with a prompt for size, and then onto another for placement, and then quantity. If you selected One of these blocks that you’d already placed and ‘create similar’ you’d get the first prompt (size)…
Whereas a straight copy you’d get a copy of the result, not the opportunity to create another one with different parameters/choices at the prompts, right?

switching to purely Revit context: there is a lot of options and selection in the creation/drafting workflow - it seems like you are always ticking boxes and setting heights or quantities or lengths or something.

Ie. in Revit To draw a wall:
You first click the wall tool, then choose the type of wall from an often long list of predefined wall types, then chose the height you want to make it, what to codify it, and a whole range of other data points (Not necessarily set in that order - but at some point you need to choose or match properties all that info into every wall)
Then you draw the wall or walls (you can draw chains of walls like using a poly line tool). The wall drawing workflow is quite intuitive, with dynamic dimensions as you draw, and the opportunity to stop, drag walls/direct enter sizes, then start again by snapping to any part of any wall and continue drawing.
If you then want to make another wall or chain of walls ‘copy’ would give you the same wall, but at the same length and orientation, you could rotate and stretch? But that’s just one, what if you want to start the polyline-like wall drawing workflow again? That’s where create similar works well. It also saves you clicking the ‘Wall’ tool, scrolling through a long list of predefined wall types, setting height, etc. you can just start drawing again.

Or in the case of placing families (also chosen from a list) you can just create similar and place away!. Sure you can copy, but copy requires a rotate to set orientation. Placing a family from scratch let’s you press Spacebar to rotate while hovering before you click to place it, so the single placement click gets you a pre-rotated object.

Revit also remembers your last choices, which is great, but if you draw a chain of wall type L, then a few wall type G, then want another chain of wall type L Create Similar can help.

It could be top 5 used commands in Revit. Up there with Copy, Rotate, Move and the Design Building and AutoMagically Document It command :joy:

Wordy, but hopefully it helps?

‘Copy’ duplicates an object. ‘Create similar’ invokes the command that created the original object.

Well, as there are often many commands for creating the same type of object and the fact that an object can be modified at any time, this seems to me to be of limited usefulness.

If the original is a sharply defined object type such as a line, a polyline, a circle or perhaps a rectangular plane surface, yes, that’s easy. If it’s a spline curve, was it created by Curve, InterpCrv, some other curve command, or by joining several other curve elements together? If it’s a freeform surface or a polysurface, what command should be invoked?

The simplest and foremost maybe… in case of a CV curve maybe just the ‘Curve’ command.
I don’t see it as a problem that this CS command won’t have any specific intelligence. I would know that when I need a special modelling step, I’d have to use the proper command. For many other cases, like the ones you mentioned, it would be quite handy.
I know this from my Revit experience.

Dimensioning is another example. Got some e.g. radial dimensions, select one of then, enter cv, and off you go for another. Yes, you could put ‘DimRadius’ on an alias, but the nice thing about CS is that it’s the same alias for all. Less toolbar clicking, less typing… can only help.

Edit: basically what the ‘What’ command says an object is. Simple.
Might be easy to script that. When I find the time, I’ll give it a try…

1 Like

Not too hard - it’s basically a lookup table. Get the object type and run the Rhino command that creates it. You will just need a very long list of object types and the corresponding the command strings to run for each one.

1 Like

Yes… and if it’s not in the list, it doesn’t work. Not a problem when most of the basic object types do.

1 Like

Alright so… 4 years later…I find myself actually wanting this functionality as well @Helvetosaur @Eugen @Prehabitat

My use case is a little different in that I create “control geometry” that gets fed into scripts and grasshopper to create functions.

So I may have a polyline that I drew of type “wall” but another curve maybe of type “floor”.

By running create similar, I can invoke the command that creates said polyline while also utilizing match properties to ensure the user text of the new polyline is the same and goes to the proper layer structure such as “Architecture::Walls” or “Architecture::Floors”

This is particular useful in cases such as “Doors” or “Electrical Outlets” where more specific user text may have been created that controls an algorithm and sure I could just “copy/paste” said point “Door” or point “Electrical Outlet” but I’d rather have the ability to select the outlet, then run Create Similar and now I can place a point anywhere while leveraging Rhino’s smart tracking and snapping capabilities instead of just a copy/paste or gumball Alt+Pan copy kind of thing…

Sure I could make a command/macro where I just type “wall” and it makes the wall the default layer but I find it much easier to invoke a “create similar” kind of functionality because to @Eugen’s point, it’s one shortcut/alias for many object types.

I mostly just care about points, lines, polylines, and surfaces at this point but I’d be curious how to expand/optimize the idea with a table or some more efficient means.

right now I’m repeating a lot of code to determine what subcurve type it is for instance.

Point is obviously the easiest. Breps could get tricky…

But just focusing on points and basic lines/polylines for now here’s the code i’ve come up with thus far that could be run from a CS alias or similar.

I would love yall’s ideas for improvement!

import rhinoscriptsyntax as rs
import Rhino

def create_similar():
    # Check if an object is preselected
    selected_object = rs.GetObject("Select an object to create a similar one", preselect=True)
    if selected_object:
        print("Object preselected.")
    else:
        # If no object is preselected, prompt the user to select one
        selected_object = rs.GetObject("Select an object to create a similar one")
        if not selected_object:
            print("No object selected. Aborting.")
            return

    # Get the Rhino document
    doc = Rhino.RhinoDoc.ActiveDoc
    # Get the Rhino object corresponding to the selected object
    rhino_object = doc.Objects.Find(selected_object)

    if rhino_object:
        # Get the geometry of the Rhino object
        geometry = rhino_object.Geometry
        # Check if the geometry is a curve
        if isinstance(geometry, Rhino.Geometry.Curve):
            # Check if the curve is a line
            if isinstance(geometry, Rhino.Geometry.LineCurve):
                start_point = rs.GetPoint()
                end_point = rs.GetPoint()
                new_curve = rs.AddLine(start_point, end_point)
            # Check if the curve is an arc
            elif isinstance(geometry, Rhino.Geometry.ArcCurve):
                start_point = rs.GetPoint()
                end_point = rs.GetPoint()
                center_point = rs.GetPoint()
                new_curve = rs.AddArc3Pt(start_point, end_point, center_point)
            # Check if the curve is a polyline
            elif isinstance(geometry, Rhino.Geometry.PolylineCurve):
                polyline = geometry.ToPolyline()
                user_points = rs.GetPoints()
                new_curve = rs.AddPolyline(user_points)
            else:
                print("Unsupported curve type. Aborting.")
                return

            # Match properties including layer and user text
            if new_curve:
                rs.MatchObjectAttributes(new_curve, selected_object)
        elif isinstance(geometry, Rhino.Geometry.Point):
            # Prompt the user to create a new point
            point_location = rs.GetPoint("Pick a location to add point")
            if point_location:
                # Create a new point object
                new_point_object = rs.AddPoint(point_location)
                # Match properties including layer and user text
                rs.MatchObjectAttributes(new_point_object, selected_object)
        else:
            print("Unsupported object type. Aborting.")
            return
    else:
        print("Unable to find Rhino object. Aborting.")

# Call the function to execute the script
create_similar()