Stamp with python

hello…
on layouts, sometimes i need to add a symbol, i would like to make a python scipt, that it make the polyline and i’ve just to click to put it where i want.
there is two versions of this symbol, and i can rotate it every 90°, i know how i can change this, but i don’t know how i can have the dynamic preview at the end of my mouse’s cross…

is it clear?

Hi @onlyforpeace,

Let me know if this sample gives you any ideas:

import Rhino
import scriptcontext as sc
import System

def make_symbol():
    points = []
    points.append(Rhino.Geometry.Point3d(0.0, 5.0, 0.0))
    points.append(Rhino.Geometry.Point3d(-5.0, 0.0, 0.0))
    points.append(Rhino.Geometry.Point3d(-2.0, 0.0, 0.0))
    points.append(Rhino.Geometry.Point3d(-2.0, -5.0, 0.0))
    points.append(Rhino.Geometry.Point3d(2.0, -5.0, 0.0))
    points.append(Rhino.Geometry.Point3d(2.0, 0.0, 0.0))
    points.append(Rhino.Geometry.Point3d(5.0, 0.0, 0.0))
    points.append(Rhino.Geometry.Point3d(0.0, 5.0, 0.0))
    pline = Rhino.Geometry.Polyline(points)
    return pline.ToPolylineCurve()

class get_symbol_point(Rhino.Input.Custom.GetPoint):
    
    def __init__(self):
        self.m_curve = make_symbol()
        self.m_xform = Rhino.Geometry.Transform.Identity
    
    def CalculateTransform(self, point):
        xform = Rhino.Geometry.Transform.Identity
        dir = point - Rhino.Geometry.Point3d.Origin
        if (not dir.IsTiny()):
            xform = Rhino.Geometry.Transform.Translation(dir)
        return xform
    
    def OnMouseMove(self, e):
        self.m_xform = self.CalculateTransform(e.Point)
        GetPoint.OnMouseMove(self, e)
    
    def OnDynamicDraw(self, e):
        curve = self.m_curve.DuplicateCurve()
        curve.Transform(self.m_xform)
        e.Display.DrawCurve(curve, System.Drawing.Color.Cyan)
        GetPoint.OnDynamicDraw(self, e)    
    
def test_place_symbol():
    
    gp = get_symbol_point()
    gp.SetCommandPrompt("Symbol location")
    gp.Get()
    if gp.CommandResult() <> Rhino.Commands.Result.Success:
        return
        
    xform = gp.CalculateTransform(gp.Point())
    curve = make_symbol()
    curve.Transform(xform)
    sc.doc.Objects.AddCurve(curve)
    sc.doc.Views.Redraw()

if( __name__ == "__main__" ):
    test_place_symbol()

– Dale

Ok, that’s it’s!!!
whouaou… but i was thinking it will be easier!!!
what does mean:

if (not dir.IsTiny()):

and if i want to have option on the script like:

    rot = Rhino.Input.Custom.OptionInteger(rot, 0, 3)
    sens = Rhino.Input.Custom.OptionToggle(sens, "devant", "derrière")
    gp.AddOptionInteger("Rotation",rot)
    gp.AddOptionToggle("Sens_Coupe",sens)

Hello,

It does not apply the transformation if it is extremely small

https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Vector3d_IsTiny_1.htm

It would be a good idea to rename dir to translation or similar : dir is a reserved word in python.

Graham

1 Like
if (...):

is not python syntax ???

how can it’s possible to mix diferent syntax? it’s creazy… no?

if() is OK in python

The (...) are not needed but can make it clearer that you are evaluating everything inside the parentheses. In Python if you put a single expression in parenthesis then the parentheses are simply removed when that line is evaluated. If you put more than one item, or add a trailing comma, then it becomes a tuple. This can cause confusion :upside_down_face:

>>> bool((False))
False
>>> bool((False, ))
True

And if you would like to go further down the rabbit hole of boolean logic in Python then I came across this blog post today (including lots of details of the Cpython implementation) !

Hi @dale!!

so i found how i can change the stamp design, but the preview at the end of my mousse cross, doesn’t refresh… where in the script i can refresh the stamp???

    gp = get_symbol_point()
    gp.SetCommandPrompt("Symbol location")
    rot = Rhino.Input.Custom.OptionInteger(rotcurrentvalue, 0, 3)
    sens = Rhino.Input.Custom.OptionToggle(senscurrentvalue, "devant", "derrière")
    gp.AddOptionInteger("Rotation",rot)
    gp.AddOptionToggle("Sens_Coupe",sens)
    
    while True:
        gp.Get()
        if gp.CommandResult() == Rhino.Commands.Result.Cancel:
            return
        res=gp.Result()
        if res==Rhino.Input.GetResult.Option:
            gp.MaJSymbol(rot,sens)
        else:
            xform = gp.CalculateTransform(gp.Point())
            curve = make_symbol(rot,sens)
            curve.Transform(xform)
            sc.doc.Objects.AddCurve(curve)
            sc.doc.Views.Redraw()

arghhhh!!!
i need help…

i post my script below, but can you explain me why that de preview doesn’t refresh when i change option,
i think it is when i update the stamp, i need to initialize the self.m_curve.DuplicateCurve().
no?

# coding: utf-8
import Rhino
from math import radians
import scriptcontext as sc
import System

def make_symbol(rot,sens):
    try:
        rotation=rot.CurrentValue
    except:
        rotation=rot
    try:
        sensp=sens.CurrentValue
    except:
        sensp=sens
    points = []
    if sensp:
        points.append(Rhino.Geometry.Point3d(0.0, 5.0, 0.0))
        points.append(Rhino.Geometry.Point3d(-5.0, 0.0, 0.0))
        points.append(Rhino.Geometry.Point3d(-2.0, 0.0, 0.0))
        points.append(Rhino.Geometry.Point3d(-2.0, -5.0, 0.0))
        points.append(Rhino.Geometry.Point3d(2.0, -5.0, 0.0))
        points.append(Rhino.Geometry.Point3d(2.0, 0.0, 0.0))
        points.append(Rhino.Geometry.Point3d(5.0, 0.0, 0.0))
        points.append(Rhino.Geometry.Point3d(0.0, 5.0, 0.0))
    else:
        points.append(Rhino.Geometry.Point3d(0.0, 1.0, 0.0))
        points.append(Rhino.Geometry.Point3d(-2.5, 0.0, 0.0))
        points.append(Rhino.Geometry.Point3d(-1.0, 0.0, 0.0))
        points.append(Rhino.Geometry.Point3d(-1.0, -5.0, 0.0))
        points.append(Rhino.Geometry.Point3d(1.0, -5.0, 0.0))
        points.append(Rhino.Geometry.Point3d(1.0, 0.0, 0.0))
        points.append(Rhino.Geometry.Point3d(2.5, 0.0, 0.0))
        points.append(Rhino.Geometry.Point3d(0.0, 1.0, 0.0))


    if rotation == 0:
        pline = Rhino.Geometry.Polyline(points)
        return pline.ToPolylineCurve()
    elif rotation == 1:
        pline = Rhino.Geometry.Polyline(points)
        #Rform=Rhino.Geometry.Transform.Rotation(Rhino.Geometry.Vector3d(1,0,0),Rhino.Geometry.Vector3d(0,1,0),Rhino.Geometry.Point3d(0,0,0))
        Rform=Rhino.Geometry.Transform.Rotation(radians(90),Rhino.Geometry.Point3d(0,0,0))
        pline.Transform(Rform)
        return pline.ToPolylineCurve()
    elif rotation == 2:
        pline = Rhino.Geometry.Polyline(points)
        #Rform=Rhino.Geometry.Transform.Rotation(Rhino.Geometry.Vector3d(1,0,0),Rhino.Geometry.Vector3d(-1,0,0),Rhino.Geometry.Point3d(0,0,0))
        Rform=Rhino.Geometry.Transform.Rotation(radians(180),Rhino.Geometry.Point3d(0,0,0))
        pline.Transform(Rform)
        return pline.ToPolylineCurve()
    elif rotation == 3:
        pline = Rhino.Geometry.Polyline(points)
        #Rform=Rhino.Geometry.Transform.Rotation(Rhino.Geometry.Vector3d(1,0,0),Rhino.Geometry.Vector3d(0,-1,0),Rhino.Geometry.Point3d(0,0,0))
        Rform=Rhino.Geometry.Transform.Rotation(radians(270),Rhino.Geometry.Point3d(0,0,0))
        pline.Transform(Rform)
        return pline.ToPolylineCurve()

class get_symbol_point(Rhino.Input.Custom.GetPoint):
    
    def __init__(self):
        self.rotation=0
        self.sens=True
        self.m_curve = make_symbol(self.rotation,self.sens)
        self.m_xform = Rhino.Geometry.Transform.Identity
    
    def CalculateTransform(self, point):
        xform = Rhino.Geometry.Transform.Identity
        dir = point - Rhino.Geometry.Point3d.Origin
        if (not dir.IsTiny()):
            xform = Rhino.Geometry.Transform.Translation(dir)
        return xform
    
    def OnMouseMove(self, e):
        self.m_xform = self.CalculateTransform(e.Point)
        GetPoint.OnMouseMove(self, e)


    def MaJSymbol(self,rot,sens):
        self.m_curve = make_symbol(self.rotation,self.sens)

    def OnDynamicDraw(self, e):
        curve = self.m_curve.DuplicateCurve()
        curve.Transform(self.m_xform)
        e.Display.DrawCurve(curve, System.Drawing.Color.Red)
        GetPoint.OnDynamicDraw(self, e)    
    
def test_place_symbol():
    
    if sc.sticky.has_key('rotation'):
            rotcurrentvalue=sc.sticky['rotation']
    else:
        rotcurrentvalue=0
    if sc.sticky.has_key('sens'):
            senscurrentvalue=sc.sticky['sens']
    else:
        senscurrentvalue=True
        
    gp = get_symbol_point()
    gp.SetCommandPrompt("Symbol location")
    rot = Rhino.Input.Custom.OptionInteger(rotcurrentvalue, 0, 3)
    sens = Rhino.Input.Custom.OptionToggle(senscurrentvalue, "devant", "derrière")
    gp.AddOptionInteger("Rotation",rot)
    gp.AddOptionToggle("Sens_Coupe",sens)
    
    while True:
        gp.Get()
        if gp.CommandResult() == Rhino.Commands.Result.Cancel:
            return
        res=gp.Result()
        if res==Rhino.Input.GetResult.Option:
            gp.MaJSymbol(rot,sens)
        else:
            xform = gp.CalculateTransform(gp.Point())
            curve = make_symbol(rot,sens)
            curve.Transform(xform)
            sc.doc.Objects.AddCurve(curve)
            sc.doc.Views.Redraw()

if( __name__ == "__main__" ):
    test_place_symbol()

Hi @onlyforpeace,

See if this helps.

test_place_symbol.py (4.8 KB)

– Dale

1 Like

YEEEEEEEEEEEEEEEES IT ISSSSSSSSSSSSSSS!!!

Thank You @dale!!!

i would like to find by myself, I’ll inspect your code to find where I’m wrong!!

My error is here:

I declared ‘Rotation’ and ‘sens’ to make the m_curve, so it can never change it…
in yours you pass ‘Rotation’ and ‘sens’ in Argument!!!

@dale, now i want that my symbol, as more than one line, maybe two or three lines…
does self.m_curves.DuplicateCurve() will run? i’m not sure, is there a simple way to change it?
can i use a

for m_curve in m_curves:
   self.m_curve.DuplicateCurve()

does the

e.Display.DrawCurve(curve, System.Drawing.Color.Red)

will run with a list?

so… I tried a lot of thing but without solution… the preview doesn’t run and i don’t know why… if someone can explain me why my def OnDynamicDraw(self, e): doesn’t run…
my script:STAMP3.py (4.3 KB)

thank’s!

hello @dale, it’s really strange because, in my new script, it’s like python doesn’t visit my
def OnDynamicDraw(self, e): if i write a syntax mistake it doesn’t return an error,
and in your script, if i add an equal symbol in the def OnDynamicDraw(self, e): to make a syntax mistake, python doesn’t return an error, it run but without preview…
it’s difficult to debugg it if python doesn’t return anything…
where is the mistake in :

    def OnDynamicDraw(self, e):
        for line in self.m_lines:
            dline = line.DuplicateCurve()
            dline.Transform(self.m_xform)
            e.Display.DrawCurve(dline, System.Drawing.Color.Red)
            GetPoint.OnDynamicDraw(self, e)

hello…

Any idea???

so… i searched an i found, where was the error? i’m not sure, i don’t really know, but it’s ok know…

thank you for your help, i understood a lot of thing with this script!!

hello!!

is there some changes for python Between Rh6 and Rh7?

my script run on V6 but no on V7…

X_COUPE_TUBE_STAMP.py (6.0 KB)

Hello,

Your script runs for me on Rhino 7 (I am not on the latest Version 7)
(7.0.20314.3001, 09/11/2020)

yes… me too…
it didn’t run, and now it run… it’s really strange…