예제 #1
0
    def make(self):
        group = rs.AddGroup()

        if (self.hexShape.length == 6):
            r = range(-1, self.hexShape.length - 1)
        else:
            r = range(self.hexShape.length - 1)

        for i in r:
            srf = self.makeTriangleSrf(i)
            unroll = self.makeUnrollPattern(i)

            self.srfList.append(srf)
            self.unrollList.append(unroll)
        #

        txt = rs.AddTextDot(
            str(self.name),
            self.hexProjection.centerPt,
        )

        rs.AddObjectsToGroup(txt, group)
        rs.AddObjectsToGroup(self.srfList, group)
        rs.AddObjectsToGroup(self.unrollList, group)

        return self
예제 #2
0
def framemulti(srfs):
    rs.EnableRedraw(False)
    rs.SelectObjects(srfs)
    rs.Command("reparameterize a")
    rs.UnselectAllObjects()
    frames = []
    allgroup = rs.AddGroup()
    for srf in srfs:
        group = rs.AddGroup()
        frame = []
        if option == 2:
            frame.append(isoframe(srf, 0, intervalx, vec2))
        elif option == 1:
            frame.append(isoframe(srf, 0, intervalx, vec2))
            frame.append(extframe(srf))
        else:
            frame.append(isoframe(srf, 0, intervalx, vec2))
            frame.append(isoframe(srf, 1, intervaly, vec2))
            frame.append(extframe(srf, vec1))
        frame = [x for x in frame if x]
        frame = list(reduce(lambda x, y: x + y, frame))
        rs.AddObjectsToGroup(frame, group)
        frames.append(frame)
        # print frame
    # for frame in frames: rs.SelectObjects(frame)
    frames = [x for x in frames if x]
    frames = list(reduce(lambda x, y: x + y, frames))
    rs.AddObjectsToGroup(frames, allgroup)
    rs.SelectObjects(frames)
    rs.EnableRedraw(True)
    return frames
예제 #3
0
    def unroll(self):
        x = 0

        for i in range(len(self.srfList)):
            g = rs.AddGroup()

            s, p = rs.UnrollSurface(self.srfList[i], False, self.unrollList[i])

            s = rs.JoinSurfaces(s, True)

            p = rs.MoveObjects(p, [x, self.name * 10, 0])
            s = rs.MoveObject(s, [x, self.name * 10, 0])

            b = rs.DuplicateSurfaceBorder(s, 1)

            rs.ObjectLayer(b, "cut")

            rs.AddObjectsToGroup(b, g)
            rs.AddObjectsToGroup(p, g)

            bb = rs.BoundingBox(s)
            x += fabs(bb[0].X - bb[1].X) + 1

            t = rs.AddText(
                str(self.name) + "-" + str(i),
                util.averagePt(rs.CurvePoints(b)), 0.3)

            t = util.makeEngravingFont(t)

            rs.AddObjectsToGroup(t, g)

            rs.DeleteObjects(s)
예제 #4
0
 def show_specialized(self, island):
     curve_id = self.show_line(island)
     island.cut_edge_lines.append(curve_id)
     if self.has_outer_joinery:
         curves = island.joinerySystem.outer_joinery(curve_id,
                                                     left_side=False)
         rs.AddObjectsToGroup(curves, self.group_name)
     else:
         rs.ReverseCurve(
             curve_id)  #necessary to reverse direction so edges match
         curves = island.joinerySystem.inner_joinery(curve_id,
                                                     left_side=False)
         rs.AddObjectsToGroup(curves, self.group_name)
예제 #5
0
def main():

    cyls = []
    radius = 0

    gname = "Enclosure"

    extantGroups = rs.GroupNames()
    print "groups: ", extantGroups
    enclosures = [s for s in extantGroups if "Enclosure" in s]
    print "enclosures: ", enclosures

    if rs.IsGroup("Enclosure"):
        num = len(enclosures)
        gname += "_" + ` num `
    encGroup = rs.AddGroup(gname)
    print "group: ", encGroup

    focus = rs.GetPoint("center of fence")
    if (focus is None): return
    rpt = rs.GetPoint("enclosure radius", focus)
    if (rpt is None): return
    else:
        radius = (rpt - focus).Length
        rs.AddObjectsToGroup(rs.AddCircle(focus, radius), encGroup)

    count = rs.GetInteger("number of cylinders")
    if (count is None): return
    cyldiam = rs.GetReal("cylinder diameter")
    if (cyldiam is None): return
    minheight = rs.GetReal("minimum height")
    if (minheight is None): return
    maxheight = rs.GetReal("maximum height")
    if (maxheight is None): return
    #   arcjitter = rs.GetReal("amount of arc jitter")
    #   if (arcjitter is None): return
    #   radialjitter = rs.GetReal("amount of radial jitter")
    #   if (radialjitter is None): return

    for i in range(count):
        cyl = rs.AddCylinder(rpt, random.uniform(minheight, maxheight),
                             cyldiam / 2, True)
        rs.RotateObject(cyl, focus, (360 / count) * (i + 1))
        cyls.append(cyl)
    if cyls: rs.AddObjectsToGroup(cyls, encGroup)
    print "Enclosure built:"
    print "focus: (", focus, ")"
    print "radius:", radius
    print "cylinders:", count, "ranging from", minheight, "to", maxheight, "units in length."
def outputFunc(objs):
    """Extracts the bottom faces of each solid in selection

    Args:
        objs (list of ids): list of ids

    Returns:
        list: list of bottom faces
    """

    rs.EnableRedraw(False)
    bottomFaces = []
    for obj in objs:
        resultFaces = trp.getBottomFace(obj)
        # print resultFaces
        for resultFace in resultFaces:
            trp.copySourceLayer(resultFace, obj)
            try:
                trp.copySourceData(resultFace, obj)
            except:
                pass
            bottomFaces.append(resultFace)
    rs.SelectObjects(bottomFaces)
    group = rs.AddGroup()
    rs.AddObjectsToGroup(bottomFaces, group)
    rs.EnableRedraw(True)
    return bottomFaces
예제 #7
0
def drawVectors(pts, vects, scale=3000):
    gen = []
    for p, v in zip(pts, vects):
        gen.append(rs.AddLine(p, p + rs.VectorScale(v, scale)))

    rs.AddGroup('Trash')
    rs.AddObjectsToGroup(gen, 'Trash')
예제 #8
0
    def update(self):
        print('update')
        #delete last generated objects
        try:
            rs.DeleteObjects(self.generatedObjs)
            self.generatedObjs = []
        except:
            print('exception in delete generated object')

        divWidth = 600
        crv = self.baseCrv
        if not rs.IsObject(crv):
            print('crv is not an object')
            return

        if not rs.IsPolyline(crv):
            pts = rs.DivideCurveEquidistant(crv, divWidth)
            rail = rs.AddPolyline(pts)
        else:
            rail = rs.CopyObject(crv)

        pts = rs.CurveEditPoints(rail)
        if len(pts) < 3:
            print('too little points')
            return

        #find vectors to move and orient the profile
        vect = pts[1] - pts[0]
        vect = rs.VectorUnitize(vect)
        a = rs.VectorAngle(vect, (0, 1, 0)) - 90

        #load the component
        path = self.loadPath
        component = None
        try:
            component = importComponent(path)
        except:
            print('exception on importing module')

        if component is None:
            print('component is None')
            return None

        #rs.MoveObjects(component.breps,pts[0])
        #rs.RotateObjects(component.breps,pts[0],a)
        for b in component.breps:
            self.generatedObjs.append(b)
            oriented = orientObjAlongPolyPts(b, pts)
            print('pts count:', len(pts), ' num gen:', len(oriented))

        rs.MoveObjects(component.polys, pts[0])
        rs.RotateObjects(component.polys, pts[0], a)
        for c in component.polys:
            self.generatedObjs.append(c)
            mesh = meshSwipPolyAlongPoly(c, rail)
            self.generatedObjs.append(mesh)
        rs.DeleteObject(rail)
        print('generated obj count:', len(self.generatedObjs))
        rs.AddGroup('gen')
        rs.AddObjectsToGroup(self.generatedObjs, 'gen')
예제 #9
0
def annotationBalloon():
    """
    adds leader with text and dot and a table with block name and count.
    tested in Rhino 6 for Windows, won't work in Rhino 5
    works together with addPartList_v01.py
    version 0.2
    www.studiogijs.nl
    """

    name = getBlockName()
    if not name:
        return
    curve, v, size = getInput()
    if curve and v and size:
        aCircle, aText, aCurve = addAnnotationCircle(curve, v, size)
        aEndDot = addEndDot(curve, size)
    else:
        return
    #create annotation object
    groupname = 'annotation-object_' + str(v)
    rs.AddGroup(groupname)
    rs.AddObjectsToGroup([aCircle, aText, aCurve, aEndDot], groupname)

    groups = sc.doc.ActiveDoc.Groups
    for group in groups:
        if group.Name == groupname:
            group.SetUserString("group-nr", str(v))
            group.SetUserString("block-name", name)
예제 #10
0
 def new(cls, layer, position):
     """Receives:
         layer           str. The name of the layer
         position        point3d. The position of the arrow
     Creates an arrow-name group with the name <name>-labeled-arrow. 
     Inserts it at the arrow position. Returns:
         group_out       str. The name of the new group, if successful. 
                         None otherwise.
     """
     group = '%s-labeled-arrow' % layer
     arrow_instance = a.Arrow.new_instance(layer, position)
     text_position = rs.PointAdd(position,
                                 s.Settings.arrow_label_offset_from_arrow)
     rs.CurrentLayer(layer)
     arrow_text = rs.AddText(layer,
                             text_position,
                             height=2,
                             justification=2)
     rs.CurrentLayer(s.Settings.default_layer_name)
     group_out = rs.AddGroup(group)
     n_objects_added = rs.AddObjectsToGroup([arrow_instance, arrow_text],
                                            group)
     if n_objects_added:
         return_value = group_out
     else:
         return_value = None
     return return_value
예제 #11
0
def LockAllOtherLayers():
    try:
        obj = rs.GetObject(message="Select the object on the layer you want to stay unlocked", filter=0,
                           preselect=True, select=False, custom_filter=None, subobjects=False)

        rs.EnableRedraw(False)

        groupName = random.random()

        layer = rs.ObjectLayer(obj)
        objs = rs.ObjectsByLayer(layer, select=False)
        allobj = rs.AllObjects(select=True, include_lights=False,
                               include_grips=False, include_references=False)
        rs.UnselectObjects(objs)
        toBeLockedObj = rs.SelectedObjects()
        rs.UnselectAllObjects()

        group = rs.AddGroup(groupName)
        rs.AddObjectsToGroup(toBeLockedObj, group)

        rs.LockGroup(groupName)

        rs.DeleteGroup(groupName)

        rs.EnableRedraw(True)

    except:
        rs.EnableRedraw(True)
        print("Failed to execute")
        return
예제 #12
0
def draw_mesh(mesh, layer=None):
    # if quad/tri mesh add mesh, else add edges

    if mesh.number_of_vertices() == 0:
        return None

    for fkey in mesh.faces():
        if len(mesh.face_vertices(fkey)) > 4:
            #return edges
            rs.EnableRedraw(True)
            edges = [
                rs.AddLine(mesh.vertex_coordinates(u),
                           mesh.vertex_coordinates(v))
                for u, v in mesh.edges()
                if mesh.vertex_coordinates(u) != mesh.vertex_coordinates(v)
            ]
            rs.EnableRedraw(False)
            group = rs.AddGroup()
            rs.AddObjectsToGroup(edges, group)
            return edges
    # return mesh
    vertices, faces = mesh.to_vertices_and_faces()
    mesh_guid = rhino.utilities.drawing.xdraw_mesh(vertices, faces, None, None)

    if layer is not None:
        rs.ObjectLayer(mesh_guid, layer)

    return mesh_guid
예제 #13
0
def AddTag(obj, text, color):
    box = rs.BoundingBox(obj)
    mid = (box[0] + box[-2])/2
    tag = rs.AddTextDot(text, mid)
    rs.SetUserText(obj, 'tag', text)
    rs.ObjectColor(obj, color)
    group = rs.AddGroup()
    rs.AddObjectsToGroup([obj, tag], group)
예제 #14
0
def AddBlockName(obj):
    name = rs.BlockInstanceName(obj)
    pt = rs.BlockInstanceInsertPoint(obj)
    bb = rs.BoundingBox(obj)
    text = rs.AddText(name, (bb[0] + bb[6]) / 2)
    rs.SetUserText(text, 'tag', 'label')
    group = rs.AddGroup()
    rs.AddObjectsToGroup([obj, text], group)
예제 #15
0
def circleLine(start, end):
    circles = []
    for c in range(start, end, 1):
        anotherCircle = rs.AddEllipse((c, c, 0), random.uniform(1, 2),
                                      random.uniform(1, 2))
        circles.append(anotherCircle)
    rs.AddObjectsToGroup(circles, "lottacircles")
    print(circles)
예제 #16
0
 def add_count(self):
     self.circle = rs.AddCircle(self.point, self.radius)
     self.group_list.append(self.circle)
     self.hatch = rs.AddHatch(self.circle, hatch_pattern="SOLID")
     self.group_list.append(self.hatch)
     self.group_name = rs.AddGroup(group_name=self.id)
     objs = [self.circle, self.hatch]
     rs.AddObjectsToGroup(objs, self.id)
     self.check_center()
def MarkShortEdges():
    tol = 1
    mm = Rhino.UnitSystem.Millimeters
    units = sc.doc.ModelUnitSystem

    tol = Rhino.RhinoMath.UnitScale(mm, units)

    while True:

        if sc.sticky.has_key('EDGELENGTH_TOL'):
            tol = sc.sticky['EDGELENGTH_TOL']

        go = Rhino.Input.Custom.GetObject()

        opTol = Rhino.Input.Custom.OptionDouble(tol)
        go.AddOptionDouble("EdgeLength", opTol)
        go.AcceptNumber(True, False)
        res = go.Get()

        if (go.CommandResult() != Rhino.Commands.Result.Success):
            return
        if res == Rhino.Input.GetResult.Object:
            go.Object(0)
            break

        if res == Rhino.Input.GetResult.Option:
            tol = opTol.CurrentValue
            sc.sticky['EDGELENGTH_TOL'] = tol
            continue
        if res == Rhino.Input.GetResult.Number:
            tol = go.Number()
            sc.sticky['EDGELENGTH_TOL'] = tol
            continue

    sTol = str(round(tol, 4))

    brepId = rs.GetObject(filter=8 + 16, preselect=True)
    if brepId is None: return

    brep = sc.doc.Objects.Find(brepId).Geometry
    edges = brep.Edges

    count = 0
    for edge in edges:
        l = edge.GetLength()
        if edge.GetLength() <= tol:
            if count == 0:
                grp = rs.AddGroup()
            temp = rs.AddTextDot("!!!", edge.PointAtStart)
            rs.AddObjectsToGroup(temp, grp)
            count += 1
    if count == 1:
        msg = " edge found at or below " + sTol + " in length."
    else:
        msg = " edges found at or below " + sTol + " in length."

    print str(count) + msg
예제 #18
0
def rSet(val):
    objs = rs.GetObjects("Select objs")
    if objs:
        [rs.SetUserText(obj, key, str(val)) for obj in objs]
        group = rs.AddGroup()
        rs.AddObjectsToGroup(objs, group)
        # objs = None
        val = val + 1
        rSet(val)
예제 #19
0
def addcurvaturegraph(idCrv, spansamples, scale):
    allGeometry = []
    knots = rs.CurveKnots(idCrv)
    p = 5
    for i in range(knots.Count - 1):
        tmpGeometry = addcurvaturegraphsection(idCrv, knots[i], knots[i + 1],
                                               spansamples, scale)
        if tmpGeometry: allGeometry.append(tmpGeometry)
    rs.AddObjectsToGroup(allGeometry, rs.AddGroup())
    return allGeometry
예제 #20
0
def multiLineCurve():
    """
    --- --- --- --- --- --- --- --- --- --- ---
    -------------------------------------------
    --- --- --- --- --- --- --- --- --- --- --- 
    this script divides a curve by length and adds dashes to either side of the curve, grouped per curve / polyline
    limitation: does not accomodate at corners (to avoid ccx issues)
    www.studiogijs.nl
    """
    curves = rs.GetObjects("select curves to change into multiline-style",4, preselect=True)
    if not curves:
        return
    s=sc.sticky['scale'] if sc.sticky.has_key('scale') else 20
    scale = rs.GetReal("scale of the multiline curve", s, 5, 100)
     
    
    if not scale:
        return
    sc.sticky['scale']=scale
    
    rs.EnableRedraw(False)
    
    for curve in curves:
        lines=[]
        if rs.CurveLength(curve)>scale:
            pts = rs.DivideCurveLength(curve, scale)
            for pt in pts:
                t=rs.CurveClosestPoint(curve, pt)
                vec = rs.CurveTangent(curve, t)*scale/5
                line = rs.AddLine(pt-vec, pt+vec)
                trans = rs.VectorRotate(vec, 90, [0,0,1])
                trans/=2
                line_copy = rs.CopyObject(line, trans)
                trans = -trans
                lines.append(line_copy)
                rs.MoveObject(line, trans)
                lines.append(line)
            group = rs.AddGroup()
            rs.AddObjectsToGroup(lines, group)
            rs.AddObjectsToGroup(curve, group)
            rs.SelectObjects(lines)
            rs.SelectObjects(curves)
    rs.EnableRedraw(True)
예제 #21
0
def AddDotToObjCtr(objIDs, text, transfer=True):
    #adds a dot to object(s) bounding box center and groups dot with object(s)
    bb = rs.BoundingBox(objIDs)
    if bb:
        dotID = rs.AddTextDot(text, (bb[0] + bb[6]) / 2)
        if transfer: TransferColorLayer(dotID, objIDs[0])
        objIDs.append(dotID)
        group = rs.AddGroup()
        test = rs.AddObjectsToGroup(objIDs, group)
        return dotID
예제 #22
0
def createSectionBox(obj):
    box = rs.BoundingBox(obj)
    bb = rs.AddBox(box)
    faces = rs.ExplodePolysurfaces(bb)
    faces = [rs.FlipSurface(x) for x in faces]
    planes = [getSrfFrame(x) for x in faces]
    clips = [rs.AddClippingPlane(x, 1000, 1000) for x in planes]
    group = rs.AddGroup()
    rs.AddObjectsToGroup(clips, group)
    return clips
예제 #23
0
def draw_lpoint():
    prompt_for_label = 'Enter the label'
    text = rs.GetString(prompt_for_label)
    prompt_for_point = 'Select the point'
    point = rs.GetPoint(prompt_for_point)
    height = 2
    lpoint = rs.AddText(text, point, height)
    radius = 0.5
    sphere = rs.AddSphere(point, radius)
    group = rs.AddGroup()
    rs.AddObjectsToGroup([lpoint, sphere], group)
예제 #24
0
def planClips(lvl):
    viewname = lvl["level"] + "_view"
    tempview = rs.AddNamedView("tempview", "Top")
    view = rs.AddNamedView(viewname, tempview)
    elevation = float(lvl["elevation"])
    lvlPlane = rs.CreatePlane((0, 0, elevation))
    cutPlane = rs.PlaneFromNormal((0, 0, elevation + cutHeight), (0, 0, -1))
    planes = [lvlPlane, cutPlane]
    clips = [rs.AddClippingPlane(x, 1000, 1000, view) for x in planes]
    group = rs.AddGroup()
    rs.AddObjectsToGroup(clips, group)
    rs.DeleteNamedView(tempview)
예제 #25
0
def AddNameLayerGroupObj():
    objs=rs.GetObjects("Select objects to label",4+8+16,preselect=True)
    if not objs: return
    for obj in objs:
        name=rs.ObjectName(obj)
        if not name: name="None"
        layer=rs.ObjectLayer(obj)
        bb=rs.BoundingBox(obj)
        text="Name: {}\nLayer: {}".format(name,layer)
        dot=rs.AddTextDot(text,(bb[0]+bb[6])/2)
        group=rs.AddGroup()
        rs.AddObjectsToGroup([obj,dot],group)
예제 #26
0
def fenceCurve():
    """
    ---x---x---x---x---x---x---
    this script divides a curve by length and adds 'crosses' to it, grouped per curve / polyline
    www.studiogijs.nl
    """
    curves = rs.GetObjects("select curves to change into fence-style",
                           4,
                           preselect=True)
    if not curves:
        return

    s = sc.sticky['scale'] if sc.sticky.has_key('scale') else 20
    scale = rs.GetReal("scale of the arrow curve", s, 5, 100)

    if not scale:
        return
    sc.sticky['scale'] = scale

    rs.EnableRedraw(False)

    for curve in curves:
        lines = []
        if rs.CurveLength(curve) > scale:
            pts = rs.DivideCurveLength(curve, scale)
            for pt in pts:
                t = rs.CurveClosestPoint(curve, pt)
                vec = rs.CurveTangent(curve, t)
                line = rs.AddLine(pt - vec * scale / 10, pt + vec * scale / 10)
                rs.RotateObject(line, pt, 45)
                lines.append(line)
                line_copy = rs.RotateObject(line, pt, 90, copy=True)
                lines.append(line_copy)
            group = rs.AddGroup()
            rs.AddObjectsToGroup(lines, group)
            rs.AddObjectsToGroup(curve, group)
            rs.SelectObjects(lines)
            rs.SelectObjects(curves)
    rs.EnableRedraw(True)
예제 #27
0
def AddCoordinateTag_Button():
    objs = rs.GetObjects("Select objects to add coordinates to", 1073741853 ,preselect = True)
    if objs is None: return

    dotGroup = rs.AddGroup('DotGroup')
    rs.EnableRedraw(False)
    for obj in objs:
        try:
            rs.AddObjectsToGroup(AddCoordinateTag(obj), dotGroup)
            utils.SaveFunctionData('Drawing-Add Coordinate Tag', [len(objs), True])
        except:
            utils.SaveFunctionData('Drawing-Add Coordinate Tag', [len(objs), False])
    rs.EnableRedraw(True)
예제 #28
0
    def render(self):
        i = 0
        while i < len(self.node):
            j = 0
            while j < len(self.childOf[i]):
                joinPt = self.node[i]
                newPt = self.node[self.childOf[i][j]]
                self.twig.append(rs.AddLine(joinPt, newPt))
                j += 1

            i += 1

        rs.AddObjectsToGroup(self.twig, self.treeID)
예제 #29
0
def annotation_balloon():
    """
    Adds a numbered balloon to the document based on the numbering in part list.
    Works only with block items, similar to how this works in 'solid modelers'
    on parts in assemblies
    www.studiogijs.nl
    
    version 1.1: option for choosing between all or only top level blocks
    
    """
    
    t = sc.sticky['top_level_only'] if sc.sticky.has_key('top_level_only') else 0 #0 = top level only, 1= all blocks
    if t==None:
        t=0
    top_level_only = rs.GetBoolean("annotate top level blocks only?", ["top_level_only", "yes", "no"],t)
    if not top_level_only:
        return
    sc.sticky['top_level_only'] = top_level_only[0]
    
    name = get_blockname()
    if not name:
        return
    
    previous_layer = rs.CurrentLayer()
    #check if layer 'annotation' exist, else create it
    if not rs.IsLayer("annotation"): rs.AddLayer("annotation")
    rs.LayerColor("annotation",Col.Black)
    
    rs.CurrentLayer("annotation")
    
    block_nr = get_block_index(name)+1 
    
    curve, size = get_input()
    if curve and size:
        aCircle, aText, aCurve = add_annotation_circle(curve, block_nr, size)
        aEndDot = add_end_dot(curve, size)
    else:
        rs.CurrentLayer(previous_layer)
        return
    #create annotation object
    groupname = 'annotation-object_'+str(block_nr)
    rs.AddGroup(groupname)
    rs.AddObjectsToGroup([aCircle, aText, aCurve, aEndDot], groupname)
    
    groups = sc.doc.ActiveDoc.Groups
    for group in groups:
        if group.Name == groupname:
            group.SetUserString("group-nr", str(block_nr))
            group.SetUserString("block-name", name)
    #change back to previous layer
    rs.CurrentLayer(previous_layer)
예제 #30
0
def AutolabelPoints():
    text_height = 10
    font_name = 'Arial'
    if (sc.sticky.has_key("NumPrefix")):
        prefix = sc.sticky["NumPrefix"]
    else:
        prefix = ""

    if (sc.sticky.has_key("NumSuffix")):
        suffix = sc.sticky["NumSuffix"]
    else:
        suffix = ""

    ids = rs.GetObjects('Select points to label', 1)
    if not ids: return

    start = rs.GetInteger("Start index", 0)
    if not start: start = 0

    prefix = rs.StringBox('Numbering prefix (Cancel for none)',
                          default_value=prefix,
                          title="Number prefix")
    if not prefix: prefix = ''
    sc.sticky["NumPrefix"] = prefix

    suffix = rs.StringBox('Numbering suffix (Cancel for none)',
                          default_value=suffix,
                          title="Number suffix")
    if not suffix: suffix = ''
    sc.sticky["NumSuffix"] = suffix

    count = start + len(ids)
    padding = len(str(count))

    pad_str = '{}'.format(':0{}d'.format(padding))
    pad_str = '{' + pad_str + '}'

    dot_ids = []

    for i, id in enumerate(ids):
        num_str = pad_str.format(start + i)
        text_str = '{}{}{}'.format(prefix, num_str, suffix)
        pt = id
        dot_id = rs.AddTextDot(text_str, pt)
        #rs.TextDotFont(dot_id, font_name)
        #rs.TextDotHeight(dot_id, text_height)
        dot_ids.append(dot_id)

    rs.AddObjectsToGroup(dot_ids, rs.AddGroup())