Da macro a script

Ciao a tutti,
sono nuovo del forum e degli script in python ma con grande curiosita’ e voglia di imparare (spero…)
Vorrei capire come trasformare in script questa macro:

_Points _PersistentOnPolysurface
_Pause
_Pause
_Pause
_SelLast
_projectToCplane
_Pause
_Enter
_Pause
_Line  _Pause  _Pause
_SelLast
_Pipe C=P T=L 0.15 0.3
_Enter
_Delete
_Enter

In pratica:

  1. La macro chiede di selezionare una superficie ed inserire un punto sulla stessa (_Points _PersistentOnPolysurface).
  2. Proietta lo stesso punto sul CPlane (_projectToCplane).
  3. Chiede di collegare una line tra i 2 punti (a mano, uff…)
  4. Crea un pipe

Sono proprio curioso di vedere come lo script gestisce il _PersistentOnPolysurface, e pure la creazione in automatico del pipe tra i 2 punti.

Grazie Mille!
Luca

Ciao Luca,
…praticamente pari-pari dall’help di Py (GetPointOnSurface)

import rhinoscriptsyntax as rs

surface = rs.GetObject(“Seleziona superfice”)

if surface:

…point = rs.GetPointOnSurface(surface, “Punto su superfice”)

…if point: rs.AddPoint(point)

Si’ … va beh … ma forse Luca, essendo nuovo dell’argomento, voleva vedere uno script completo … :smile:
Che se non sbaglio richiede il Command() per eseguire la macro … almeno, io non trovo funzioni rhinoscriptsyntax per disegnare le Pipe …

Ho provato con RhinoCommon, ma non riesco a disegnare la Pipe … mi da’ errore.
Cerchero’ info in merito.
Intanto ho aggirato con un Loft, ammesso che la pipe sia giusta … non ho capito bene come devono essere le opzioni … sorry.

import Rhino

def main():
  # input superficie
  gob = Rhino.Input.Custom.GetObject()
  gob.AcceptNothing( True )
  gob.SetCommandPrompt( 'Superficie ?' )
  gob.GeometryFilter = ( 
      Rhino.DocObjects.ObjectType.Surface |
      Rhino.DocObjects.ObjectType.Brep )
  gob.Get()
  if gob.CommandResult() == Rhino.Commands.Result.Cancel:
    return
  res = gob.Result()
  if res == Rhino.Input.GetResult.Nothing:
    return
  elif res == Rhino.Input.GetResult.Object:
    obref = gob.Object( 0 )
    brep = obref.Brep()
  # input punto
  gep = Rhino.Input.Custom.GetPoint()
  gep.AcceptNothing( True )
  gep.SetCommandPrompt( 'Punto sulla superficie ?' )
  gep.Constrain( brep, -1, -1, False )
  gep.Get()
  if gep.CommandResult == Rhino.Input.GetResult.Cancel:
    return
  res = gep.Result()
  if res == Rhino.Input.GetResult.Nothing:
    return
  elif res == Rhino.Input.GetResult.Point:
    pa = gep.Point()
  # proietta
  view = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView
  cplane = view.ActiveViewport.ConstructionPlane()
  xform = Rhino.Geometry.Transform.PlanarProjection( cplane )
  pb = Rhino.Geometry.Point3d( pa )
  pb.Transform( xform )
  # cerchi
  ca = Rhino.Geometry.Circle( cplane, pa, 0.15 )
  cb = Rhino.Geometry.Circle( cplane, pb, 0.3 )
  cua = Rhino.Geometry.ArcCurve( ca )
  cub = Rhino.Geometry.ArcCurve( cb )
  # tronco di cono
  breps = Rhino.Geometry.Brep.CreateFromLoft(
      [ cua, cub ],
      Rhino.Geometry.Point3d.Unset,
      Rhino.Geometry.Point3d.Unset,
      Rhino.Geometry.LoftType.Normal,
      False )
  toler = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance
  brep = breps[ 0 ].CapPlanarHoles( toler )
  # disegna
  Rhino.RhinoDoc.ActiveDoc.Objects.AddBrep( brep )
  Rhino.RhinoDoc.ActiveDoc.Views.Redraw()

main()

Adesso sono di fretta …
Vediamo se qualcuno trova il tempo per lo script completo in rhinoscriptsyntax … :smiley:

Ciao a tutti

@ Giuseppe:
ho speso ore cercando il comando sbagliato… :sweat:

@ Emilio:

grande, funziona!!
Mi puoi dire la differenza tra RhinoCommon e rhinoscriptsyntax?
Non è possibile vederlo scritto in rhinoscriptsyntax cosi’ me/ce lo posso/iamo studiare??

Grazie a tutti!!
Luca

Avevo solo fatto la parte che risolveva “OnSrf”… :wink:

… E hai fatto bene. :smiley:
Era quello che non mi ricordavo … :blush:

Ho provato a completare in qualche modo, alla buona, quello che hai iniziato,
cosi’ Luca puo’ cominciare a farsi un’idea …

import rhinoscriptsyntax as rs

surface = rs.GetObject("Seleziona superfice")
if surface:
    point = rs.GetPointOnSurface(surface, "Punto su superfice")
    if point: 
        rs.EnableRedraw( False )
        p0 = rs.AddPoint(point)
        rs.UnselectAllObjects()
        rs.SelectObject( p0 )
        rs.Command( '_ProjectToCPlane N' )
        p1 = rs.FirstObject()
        li = rs.AddLine( p0, p1 )
        rs.UnselectAllObjects()
        rs.SelectObject( li )
        rs.Command( '_Pipe C=F 0.15 0.3 Enter' )
        rs.DeleteObjects( [ p0, p1, li ] )
        rs.EnableRedraw( True )

Ciao !

[EDIT]

p.s. ho cambiato le opzioni di Pipe rispetto all’originale di Luca solo per provare lo script su Rhino in inglese …

[/EDIT]

Ciao Luca,

Dunque … Giuseppe potra’ essere piu’ preciso … ma ti dico che grosso modo RhinoCommon e’ la libreria di classi usata per scrivere i plug-in. E ora, per fortuna, disponibile anche per gli script in Python.

Pur non essendo ancora completa, permette di lavorare su molte cose: oggetti ‘astratti’, cioe’ indipendenti dal documento Rhino, ovviamente oggetti Rhino (presenti nel documento), loro attributi (layer, colore etc), viste e relativi attributi (cplane etc )
Permette di costruire comandi con le stesse opzioni dei comani nativi Rhino.
Piu’ altre cose piu’ complicate che non conosco (tipo display conduit etc)

rhinoscriptsyntax e’ una libreria di funzioni scritta usando RhinoCommon, che cerca di replicare i metodi del vecchio sistema di scripting: RhinoScript su VBScript.

E’ decisamente piu’ limitata, ma permette di scrivere piu’ velocemente certe operezioni (che sono piu’ simili ai comandi Rhino veri e proprii)
Puoi usare solo gli oggetti geometrici presenti nel documento Rhino (oltre ad aggiungerne di nuovi ovviamente) e puoi fare diverse operazioni su attributi vari, viste, layer eccetera.

Adesso devo interrompere.
Spero che qualche anima buona ti posti i link per le documentazioni delle due librerie …
Ciao !

[EDIT]

Il file chm per rhinoscriptsyntax io ce l’ho in:
C:\Program Files\Rhinoceros 5.0\Plug-ins\IronPython

La documentazione sul Web per RhinoCommon e’ qui:
http://4.rhino3d.com/5/rhinocommon/

Puo’ esser anche interessante e utile il codice Python di rhinoscriptsyntax. io ce l’ho in:
C:\Users\computer\AppData\Roaming\McNeel\Rhinoceros\5.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rhinoscript

Questo su Win, per il Mac non conosco i percorsi esatti …

Per gli esempi, cerca sul Wiki. Puoi partire da qui:
http://wiki.mcneel.com/developer/home

… e naturalmente per discutere di tutto questo … vieni qui sul forum :smiley:

[/EDIT]

…con le stesse ore imparavi a farlo con Grasshopper e ti divertivi pure !!!
:smile:

Ciao a Tutti,

@ Emilio
grazie per lo script, l’ho studiato e capito (credo).

@ Giuseppe

…con le stesse ore imparavi a farlo con Grasshopper e ti divertivi pure !!!

con Grasshopper ti diverti ma vuoi mettere la soddisfazione di farti uno script? (sempre se ci arrivero’…) :sweat_smile:

ho imparato:

  1. Alcuni comandi rhinoscript
  2. La possibilita’ di inserire un comando rhino all’interno dello script attraverso Command()
  3. Gestire le variabili all’interno dello script
  4. Differenza tra RhinoCommon e Rhinoscriptsyntax

Domandina:
GetPointOnSurface() gestisce solo un punto, c’è un modo per gestire piu’ punti?

Grazie per la pazienza!!!

Luca

Hehe … grande Luca !
… Mi azzardo ad ipotizzare la nascita di una certa rivalita’ tra scriptomani e grasshopperisti …
Prevedo una dura lotta tra componenti e metodi …
Hahahahahahaha … dai , che ci divertiamo … :wink:
(… cioe’ …quando troviamo un po’ di tempo …)

Puoi usare un ciclo while:

import rhinoscriptsyntax as rs

surface = rs.GetObject("Seleziona superfice")
if surface:
    while True:
        point = rs.GetPointOnSurface(surface, "Punto su superfice")
        if not point:
            break 
        rs.EnableRedraw( False )
        p0 = rs.AddPoint(point)
        rs.UnselectAllObjects()
        rs.SelectObject( p0 )
        rs.Command( '_ProjectToCPlane N' )
        p1 = rs.FirstObject()
        li = rs.AddLine( p0, p1 )
        rs.UnselectAllObjects()
        rs.SelectObject( li )
        rs.Command( '_Pipe C=F 0.15 0.3 Enter' )
        rs.DeleteObjects( [ p0, p1, li ] )
        rs.EnableRedraw( True )

Per terminare, dai Enter invece di cliccare sulla superficie

Ciao !

AHAHAHA…!!!
La guerra dei mondi

Ciao!
“While”: parola santa! :pray:

Tanto per giocare , sulla base del primo script fatto da Emilio, ho fatto alcune modifiche collegando il pipe tra due superfici, e… funziona! :stuck_out_tongue:

#Collega un Pipe tra 2 superfici

import rhinoscriptsyntax as rs

surface = rs.GetObject("Select first surface")
if surface:
    point = rs.GetPointOnSurface(surface, "Point on surface 1")
surface1 = rs.GetObject("Select second surface")
if surface1:
    point1 = rs.GetPointOnSurface(surface1, "Point on surface 2")
    if point and point1:
        rs.EnableRedraw( False )
        p0 = rs.AddPoint(point)
        p1 = rs.AddPoint(point1)
        li = rs.AddLine( p0, p1 )
        rs.UnselectAllObjects()
        rs.SelectObject( li )
        rs.Command( '_Pipe C=R 0.15 0.3 Enter' )
        rs.DeleteObjects( [ p0, p1, li ] )
        rs.EnableRedraw( True )

Che soddisfazione!!!
Luca

Ottimo.
Hehe … ormai sei uno scriptomane a tutti gli effetti. :smiley:

Se permetti suggerisco un modo per semplificare il tuo script:
In questo caso non e’ necessario disegnare i punti nel documento Rhino.
Per disegnare la linea possiamo usare direttamente i punti ottenuti da GetObject()

import rhinoscriptsyntax as rs

surface = rs.GetObject("Select first surface")
if surface:
    point = rs.GetPointOnSurface(surface, "Point on surface 1")
surface1 = rs.GetObject("Select second surface")
if surface1:
    point1 = rs.GetPointOnSurface(surface1, "Point on surface 2")
    if point and point1:
        rs.EnableRedraw( False )
        li = rs.AddLine( point, point1 )
        rs.UnselectAllObjects()
        rs.SelectObject( li )
        rs.Command( '_Pipe C=R 0.15 0.3 Enter' )
        rs.DeleteObject( li )
        rs.EnableRedraw( True )

In questo rhinoscriptsyntax ha delle caratteristiche un po’ particolari …
( che possono facilmente confondere … )
in quanto spesso consente di usare come parametri valori di tipo diverso.
AddLine() ad esempio, come abbiamo visto, consente di partire sia da ObjectId ( Guid ), sia da oggetti Point3d (da RhinoCommon), sia da liste con tre valori (con significato X,Y,Z)
Questo grazie alla funzione coerce3dpoint(), come possiamo vedere dal listato di AddLine():


def AddLine(start, end):
    """Adds a line curve to the current model.
    Parameters:
      start, end = end points of the line
    Returns:
      id of the new curve object
    """
    start = rhutil.coerce3dpoint(start, True)
    end = rhutil.coerce3dpoint(end, True)
    rc = scriptcontext.doc.Objects.AddLine(start, end)
    if rc==System.Guid.Empty: raise Exception("Unable to add line to document")
    scriptcontext.doc.Views.Redraw()
    return rc

… per la serie: “Curiosita’ e pettegolezzi sugli script per Rhino” … :wink:

Grazie Emilio,
in questa maniera elimino 2 variabili inutili. Funziona anche con le mesh.

    rimport rhinoscriptsyntax as rs

mesh = rs.GetObject("Pick a mesh", rs.filter.mesh)

if mesh:

    point = rs.GetPointOnMesh(mesh, "First Point on mesh")

    if point: rs.AddPoint( point )
    point1 = rs.GetPointOnMesh(mesh, " Second Point on mesh")
    if point1: rs.AddPoint( point1 )
    rs.EnableRedraw( False )
    li = rs.AddLine( point, point1 )
    rs.UnselectAllObjects()
    rs.SelectObject( li )
    rs.Command( '_Pipe C=R 0.15 0.3 Enter' )
    rs.DeleteObject( li )
    rs.EnableRedraw( True )

Step successivo: integrazione del ciclo while. :ok_hand:

Ciao!!
Luca