RCommon Tipo Oggetti

def AddObjectsToGroup():
    go = Rhino.Input.Custom.GetObject()
    go.SetCommandPrompt("Select objects to group")
    go.GroupSelect = True
    go.GetMultiple(1, 0)
    if go.CommandResult()!= Rhino.Commands.Result.Success:
        return go.CommandResult()

    ids = [go.Object(i).ObjectId for i in range(go.ObjectCount)]
    index = scriptcontext.doc.Groups.Add(ids)
    scriptcontext.doc.Views.Redraw()
    if index>=0: return Rhino.Commands.Result.Success
    return Rhino.Commands.Result.Failure

ids = [go.Object(i).ObjectId for i in range(go.ObjectCount)]
dopo la riga in grassetto sopra,
creo un ciclo for per iterare ogni elemento della lista,
ma per sapere ognuno di essi che tipo di oggetto è come si fa?

mi ritorna ID di ogni elemento essendo che gli elementi sono riportati in questo modo: go.Object(i).ObjectId

ho fatto anche varie modifiche dopo anche svariate ricerche ma non riesco proprio a capire
come funziona questa guida per ricercare e come usare la sintassi corretta. . .

edit:
in VBS usavo tipo questo: Rhino.ObjectType(objs(i)) = 1
dove ogni numero corrispondeva ad un tipo di oggetto

Trovi tutto nella guida …

https://developer.rhino3d.com/api/RhinoScriptSyntax/#object-ObjectType

Sergio ti ha gia’ indicato la funzione rhinoscriptsyntax, che forse ricordi.

Per usare RhinoCommon, possiamo andare a vedere come e’ scritta quella funzione di rhinoscriptsyntax:

Qui:

rhinoscriptsyntax/object.py at rhino-6.x · mcneel/rhinoscriptsyntax · GitHub

Se cerchiamo la funzione, vediamo:

def ObjectType(object_id):
    """Returns the object type
    Parameters:
      object_id (guid): identifier of an object
    Returns:
      number: The object type if successful.
        The valid object types are as follows:
        Value   Description
          0           Unknown object
          1           Point
          2           Point cloud
          4           Curve
          8           Surface or single-face brep
          16          Polysurface or multiple-face
          32          Mesh
          256         Light
          512         Annotation
          4096        Instance or block reference
          8192        Text dot object
          16384       Grip object
          32768       Detail
          65536       Hatch
          131072      Morph control
          134217728   Cage
          268435456   Phantom
          536870912   Clipping plane
          1073741824  Extrusion
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object")
      if obj:
          objtype = rs.ObjectType(obj)
          print "Object type:", objtype
    See Also:
      ObjectsByType
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    geom = rhobj.Geometry
    if isinstance(geom, Rhino.Geometry.Brep) and geom.Faces.Count==1:
        return 8 #surface
    return int(geom.ObjectType)

E notiamo che usa una proprieta’ della classe:

GeometryBase Class (rhino3d.com)

La proprieta’ e’ questa:

GeometryBase.ObjectType Property (rhino3d.com)

… Che a sua volta restituisce un valore di questa enumeration (convertito in un intero):

GeometryBase.ObjectType Property (rhino3d.com)

L’oggetto di tipo GeometryBase, lo possiamo ricavare dall’oggetto ObjRef
con questo metodo:

ObjRef.Geometry Method (rhino3d.com)

L’oggetto ObjRef e’ quello che ottieni da:

go.Object(i)

Se ho fatto troppo casino, fai un fischio … :blush:

Sergio, Emilio grazie per le risposte

eeee il casino lo fatto io, che non ci capisco proprio nulla :upside_down_face:

Emilio se mi potresti fare uno esempio scritto ormai sono fuori uso. . .

Per la serie: quando spiegare le cose da’ soddisfazione …
:smile:

Servirebbe sapere cosa devi fare nel ciclo.
Comunque un ciclo in cui (tra le altre cose) ricavi il tipo potrebbe essere una cosa simile:

for i in range(go.ObjectCount):
# ...
  obtype = go.Object(i).Geometry().ObjectType
# ...

… E nel ciclo ci aggiungi quello che vuoi. :slight_smile:

( Non testato :blush: )

go = Rhino.Input.Custom.GetObject()

funziona funziona :wink:

Emilio potresti dettagliarmi la tua riga di codice?

fino alla prima ci sono Rhino.Input.Custom sarebbe il namespace mentre GetObject() una sua classe

ora della tua riga avevo anche provato con go.Object(i) che correggimi dovrebbe essere un metodo?

mentre ObjectType il valore finale che pure avevo messo, ma mi mancava il
Geometry() che dovrebbe anch’esso essere un metodo? (se ho cercato bene)

Geometry() comunque non fa parte dell’elenco nel namespace di Rhino.Input.Custom
quindi viene preso da tutt’altra parte (negli ultimi tutorial in C# so che ci sono modi per ereditare/collegare oggetti tra di loro forse questo è uno di quei casi) ma io (o un’altra persona) da non conoscitore di C# e sopratutto di RCommon come faccio a sapere che dopo Rhino.Input.Custom e .GetObject() e .Object(i) che comunque compaiono nell’enco di Rhino.Input.Custom dovevo aggiungere anche .Geometry()?

oltre alla conoscenza propria di chi scrive codici, oppure nel caso riesce a trovare un file di esempio proprio con ciò che gli serve, mi riesce difficile pensare che senza saperlo di per se, riesca a trovare la strada giusta.

a meno che non ci sia (probabilmente è così) un cocetto dietro alla guida che porta a capire che dopo aver iniziato con un namaspace e poi una classe ecc da un’elenco sappia che può mettere un’altra (ipotizzo) classe o metodo ecc da un’altro elenco. . . (namespace)

E quindi go e’ un oggetto di tale classe, che noi usiamo per effettuare un input di oggetti Rhino.

Certo. C’e’ prima un oggetto ( go ), poi il punto, quindi Object e poi le parentesi.
Puo’ essere solo un metodo.
Se non ci fossero state le parentesi sarebbe stata una proprieta’.

E dato che l’oggetto prima del metodo e’ go, che abbiamo visto essere un GetObject (appartenente al namespace Rhino.Input.Custom per la precisione), il metodo in questione puo’ solo essere un metodo della classe GetObject, quindi apro la documentazione e vado a cercare la classe Rhino.Input.Custom.GetObject, la apro, cerco i metodi (sono in ordine alfabetico) e tra i metodi cerco Object
Eccolo qua ! :grinning:
GetObject.Object Method (rhino3d.com)

Scusa, avevi messo dove ? Dopo Object(i) ?
E perche’ ?

Certo. E’ un metodo anche lui, e lo scrivi dopo Object(i) perche’ Object restituisce un ObjRef, come vedi dalla documentazione del metodo linkata sopra.
E Geometry e’ un metodo di ObjRef.

Ovviamente, e’ un metodo di ObjRef, cioe’ di Rhino.DocObjects.ObjRef che come namespace ha Rhino.DocObjects.

Di solito la gente non si sveglia al mattino sapendo usare RhinoCommon per miracolo …
Invece cerca negli esempi e nella documentazione, chiede sul forum.
Fa delle prove e ci ragiona sopra.
E impara poco per volta come fare.
( Se deve imparare anche OOP e C# insieme a RhinoCommon, la cosa diventa un po’ piu’ lunga … )

Lascia stare i namespace, servono solo per avere il nome completo, ad esempio, di una classe.
Non c’entrano con la logica di programmazione.

Il concetto e’ sempre lo stesso che usavi anche per gli script in VBS.
Se hai un cosa (una curva) e vuoi ricavare un’altra cosa (la Z massima),
cerchi una via, utilizzando gli strumenti disponibili (funzioni, classi, metodi ecc.)
Quindi ad esempio cerchi un esempio di script, e se non lo trovi o se non capisci come funziona, chiedi sul forum.
Alla fine arrivi a capire che devi usare la boundingbox, allora se per esempio stai usando RhinoScript,
usi uno dei metodi dell’oggetto Rhino per ottenere la boundingbox della curva.
Leggi cosa dice la documentazione: dice che quel metodo restituisce 8 punti, i primi 4 in basso e gli altri 4 in alto. Allora capisci che per avere la Z massima dovrai prendere la Z di uno dei punti in alto, ad esempio il punto con indice 4.
Per cui alla fine per ottenere il tuo scopo utilizzi tre operazioni:

  1. ricavi i punti della boundingbox
  2. estrai il punto 4
  3. estrai la Z da quel punto, cioe’ il secondo elemento della array
    Se non ricordo male potrebbe venir fuori una cosa simile
Zmax = Rhino.BoundingBox( CurveId )( 4 )( 2 )

Stessa cosa per

obtype = go.Object(i).Geometry().ObjectType

Hai un oggetto GetObject, cioe’ go
e vuoi ricavare il tipo dell’oggetto Rhino di indice i
per cui:

Cerchi tra gli esempi e chiedi sul forum.
Risulta che devi passare da un ObjRef e da una geometria ( GeometryBase ) per ottenere il tipo di oggetto.

Quindi fai i tuoi bei tre passaggi:

  1. ricavi l’ObjRef relativo all’oggetto rhino con Object(i)
  2. ricavi la GeometryBase dall’ObjRef con Geometry()
  3. ricavi il tipo (enumeration ObjectType) dalla GeometryBase con la proprieta’ ObjectType
    Che ha lo stesso nome della enumeration, non confonderti. :wink: .

Potresti scrivere una cosa come:

obref = go.Object(i)
geo = obref.Geometry()
obtype = geo.ObjectType

Ma puoi anche mettere tutto insieme e scrivere:

obtype = go.Object(i).Geometry().ObjectType

si per queste cose ormai credo che non ci dovrebbero essere problemi (in teoria, per lo meno spero)

sul fatto di fare ricerche le ho fatte
sul fatto di riaggionarci lo stesso (per le mie potenzialità)
riassumedo le mie domande con le tue risposte spero che un po si evince questo,
prima dalla guida mi era complicato anche solo reperire i riferimeti tra classi metodi ecc

è vero che una persona può avere anche 30anni di esperienza su un linguaggio di programmazione
ma poi se si approccia ad un’altro tipo di linguaggio non dico dovrebbe iniziare da zero, ma anche se
non ho tutta questa esperienza, per lo meno speravo che nelle ricerche di trovare meno complicanzioni.

è proprio questo che mi fa perdere la bussola, il fatto che Geometry() che è un metodo di ObjRef che è una classe di Rhino.DocObjects che a sua volta è un namespace ho dovuto aggiungere un secondo metodo di una seconda classe, al primo metodo della prima classe senza nemmeno aver dovuto richiamare la seconda classe con il rispettivo namespace quindi se anche avrei trovato un esempio a riguardo, senza andare ad approfondire da dove veniva fuori il Geometry() non si sarebbe mai capito che fa parte di un’altra classe e namespace tutto questo per dire, in un’altra situazione che richiamo importo uso namespace ed una classe a lei associata con il rispettivo metodo, non esiste nulla che mi porti a trovare una soluzione che mi porti a capire che dopo un metodo dovrò aggiungere un’altro metodo di un’altra classe e magari un vedere anche un minimo di sintassi per come la vedo io a questo punto oltre a Object e Geometry poteva anche servire un’altro metodo per ottenere quel che mi serviva ed io come farei a saperlo? (ovviamente oltre a chiedere nel forum senza avere un esempio. . .)

lo che anche con Py dovevo fare una cosa mai fatta e chiedevo sul forum, ma per lo meno mi veniva dato un comando/link per eseguire quell’azione andavo a vedere nella guida e per fare quella determinata cosa era tutto li, mentre qui arrivo ad un certo punto poi mi debbo andare a prendere un’altra classe/metodo da aggiungere senza nessuna indicazione che mi porti a capire che dopo Object posso accodare un’altro metodo esterno a quella classe come appunto Geometry.
scusa se mi sono dilungato ho fatto un bel papiello anche per associarmi alla frustrazione di chi fa i render :wink: alla fine anche se con barche diverse, ma siamo tutti nella stessa situazione. . .

una delle mie domande strane tanto ormai abbiamo fatto 30 facciamo anche 31:
ma potrei accodare anche altri metodi ai due Object e Geometry oppure c’é un limite?
(nel caso di conferma quindi, le combinazioni possibili sarebbero molteplici)

eeee su questo hai pienamente ragione
anche se, non vorrei peccare di presunzione, per i tutorial (basilari) che ho seguito su C# con console, a parte i concetti più complessi degli OOP ma non mi sembrano così fuori dalla mia portata, parlo se dovrei replicarli, la sintassi credo che in poco tempo la imparerei abbastanza bene i concetti un po avanzati come i metodi costruttori istanza ereditarietà mi ci vorrebbe un po di pratica ma li dovrei assimilare bene, secondo me è l’ultimo che fa sudare il RCommon ancora mi sfugge ache il solo capire come giostrarmi in esso.

pensandoci bene con il RCommon a differenza degli OOP (che bene o male un pochino già ne parlammo con il libro su Py, il C# ho comunque seguito vari tutorial) non ho avuto nessuna infarinatura che mi abbia fatto comprendere il funzionamento, e vabbe anche per questo sto facendo questo full immersion strong

anche per questo ho preferito iniziare ad usare RCommon con Py per poi nel caso passare al C#
a proposito di questo ho una domanda proprio su questo:

go = Rhino.Input.Custom.GetObject()

Rhino.Input.Custom.GetObject go = new Rhino.Input.Custom.GetObject();

accennando agli OOP giusto per capire se qualcosa mi sfugge:
se non erro nel secondo caso quello di C# li si crea una istanza giusto?
nel primo caso in Py invece non credo, quindi si può parlare sempre di OOP?

Dalle domande che fai, secondo me la prima cosa che ti blocca e’ proprio la OOP (con un po’ di C#).
Tu dici che i concetti li sai.
Ma io penso che tu abbia imparato questi concetti in astratto, ma fatichi ancora ad utilizzarli in pratica.
Non e’ strano, anzi mi sembra normale.
Imparare qualche frase e qualche semplice esempio a memoria e’ facile.
Capire cosa significa tutto cio’ in pratica e come si usano queste cose e’ un altro paio di maniche.

Non dare per scontato che la OOP ormai la sai, secondo me sei ancora un po’ confuso.
Continua a indagare la OOP, che tra l’altro ha il difetto che si porta appresso un certo numero di paroloni che all’inizio senza dubbio possono confondere.
Per capire RhinoCommon bisogna conoscere abbastanza bene i concetti della OOP.
Se no non cavi un ragno dal buco. :wink:

Ripeto: il namespace serve solo per poter avere ad esempio due classi con lo stesso nome.
Se vuoi, consideralo come parte del nome della classe.
Ma non ha nessun significato nella logica dello script.
Mentre ragioniamo sul funzionamento dello script, il namespace non ci interessa, non conta niente.
Se la classe GetObject invece che a Rhino.Input.Custom appartenesse a Rhino.Geometry, per noi sarebbe lo stesso. Lo script funzionerebbe esattamente allo stesso modo.

Dici che ti disturba “aggiungere” un metodo a un altro.
A parte che di solito per i metodi, che come sai sono delle funzioni, si parla di invocazione o richiamo … se richiamiamo un metodo sul risultato di un altro metodo, questo si fa con uno scopo preciso.

Se mi dici che hai capito questo esempio:

Dopo, e’ strano dire che non capisci perche’ sul risultato di Geometry() richiami ObjectType.
Se non e’ chiaro perche’ dopo Geometry() usiamo ObjectType, allora l’esempio non ti e’ chiaro e dobbiamo ragionarci sopra.

Mi sembra ci sia confusione tra classi e oggetti.
Per richiamare un metodo (non statico) serve un oggetto, non una classe.
Qui l’oggetto della classe GeometryBase e’ quello restituito dal metodo Geometry().
Non avrebbe senso metterci una classe.
Guarda l’esempio sopra con le tre istruzioni separate.

Come dicevamo prima:

Tu non aggiungi i metodi, piuttosto, se serve, richiami un metodo sul risultato di un altro metodo, ad esempio perche’ a te serve l’ObjectType e hai un oggetto di tipo ObjRef.
Ma la classe ObjRef non ha un metodo che ti dia il tipo di oggetto direttamente.
Quindi tu dall’oggetto ObjRef ottieni prima un oggetto GeometryBase che ti consente poi di ottenere il tuo ObjectType.

Non e’ che dopo aver richiamato un metodo tu ne richiami uno di un’altra classe qualunque.
Se il primo metodo restituisce un oggetto, allora tu su quell’oggetto puoi richiamare uno dei suoi metodi, se ti serve.

E comunque, come abbiamo visto sopra, nessuno ti obbliga a scrivere due o piu’ metodi collegati in una singola istruzione.
Puoi benissimo scomporre, come mostrato sopra, basta usare qualche variabile.
Va benissimo anche scritto cosi’.
Anzi, visto che concatenare i metodi ti confonde, non farlo per ora.
Ragiona su:

obref = go.Object(i)
geo = obref.Geometry()
obtype = geo.ObjectType

e dimentica

obtype = go.Object(i).Geometry().ObjectType`

Certo, go e’ una istanza (od oggetto, e’ lo stesso).
E non cambia niente tra C# e Python.
E’ esattamente la stessa istruzione, e ottieni esattamente lo stesso oggetto (o istanza) della classe GetObject di RhinoCommon.

Mi sembra che tu non abbia ancora le idee chiare. :slight_smile:
Ma, ripeto, e’ normale.
Non sottovalutare i concetti (io direi le manie :smile:) della OOP, assimilali poco per volta, con calma. :slight_smile:

Se tu volessi esercitarti un po’ con queste cose, eventualmente scrivere e usare qualche semplice classe per capire meglio come funziona il tutto, secondo me e’ meglio se usi C#. :slight_smile:
Python e’ un po’ diverso da questo punto di vista.

… così sarai sicuro di ricominciare da zero.

ok avevo questo dubbio per il fatto della parola chiave new in C#
ma quindi alla fine è soltanto un modo diverso di instanziare
(diciamo che il pensiero di CPython mi ha un po forviato)

ovviamente se non avevo le idee confude scriverei codici senza problemi o quasi.

aver finito da poco una serie di tutorial una sola volta certamente non’è finita qui
anzi forse adesso si inizia, infatti se ogni tanto lancio anche qualche termine
lo faccio giusto per ripassare, lo sai non sono uno che si sofferma su queste cose
però in questo caso ritengo che essendo l’argomento molto vasto, sia opportuno
incanalare i giusti argomenti per lo meno si cerca di seguire determinati binari.

era quello che volevo fare inizialmente prima in Gh e poi in VS ma in entrambi i casi ci sono delle complicazioni per poi eseguire lo script, in Py nello stesso tempo posso fare molte più prove
per testare il codice, mi conviene iniziare a capire prima qualcosa di più e poi come dici passo al C#

ps Emilio che dici, mi vorresti dare tu qualche esercizio da fare per fare pratica con RCommon
in modo che mi chiarisco le idee sulle classi metodi proprietà e su come abbinarle per usarle?

essendo che fino a quando le classi/metodi sono nell’elenco del namespace è un conto
ma se debbo iniziare ad usare classi e metodi da altri namespace mi perdo per strada

mi sarebbe utile vedere un paio di esempi “semplici” da te fatti combinando classi e metodi
e poi mi chiederesti di fare un esercizio spiegando sommariamente come combinarle
da un paio di namespace che servono per ottenere il risultato che hai chiesto.

in modo che non avrei la soluzione, ma comunque un certo indirizzo
quindi navigherei in un mare e non nell’oceano di RCommon

hai ragione Sergio, ma come detto ad Emilio, scrivere i codici tramite editor di Rhino è un conto
se debbo usare VS per poi dover creare un file RHP installarlo e poi fare la verifica
su ogni modifica che faccio al codice, mi diventa davvero complicata la cosa.

quindi penso che sia meglio farmi prima le ossa usando RCommon con l’editor di Py

Io parlavo di una cosa diversa: esercitarsi con C# senza RhinoCommon, e per quello basta usare Mono o anche GH, e suppongo anche altre cose …
Ma se tu preferisci usare RhinoCommon, OK.
Allora certo Python e’ piu’ comodo.
A meno che tu riesca a usare RhinoCode sulla WIP … io questo non lo so.

Ci provo … :slight_smile:

1 Mi Piace

questo lo sto proprio facendo adesso con VS
faccio pratica sulle cose che vedo nei tutorial
ma ovviamente solo inerente al linguaggio C#
sto ripassando gli Array e le Liste ovviamente
all’inizio ci si va ad intrecciarsi con la sintassi

per forza lo debbo fare, vedere il video
una sola volta la vedo difficile per tutti
per sentirsi padroni del linguaggio. . .

alla fine sono sempre if for while ecc
ho capito che C# è tipizzato quindi
ha bisogno di specificargli tutto
poi ci sono gli Array ArrayList List
ognuno con la propria sintassi

su queste cose dicevo che mi basta
un po di pratica, poi i concetti delle
cose più avanzate +/- non comprese
ma un po afferrate questo si, poi come
hai detto metterle in pratica è altra cosa

grazie sempre della disponibilità
(un paio di cose molto molto basilari)
che se riesco a capire come orientarmi
nella guida di RCommon e prendendo
confidenza con C# in VS credo che poi
capire come funzionano meglio gli OOP
vien da se ovviamente più fai meglio è :+1:

Quindi non sei ancora alle classi.
Credo sia per quello che fatichi con RhinoCommon.

Quanto all’esempio/esercizio …
( Premesso che se non hai studiato le classi io direi di aspettare di studiarle … )
Qui ci sono alcune (molto semplici) operazioni con alcuni (molto semplici) tipi di oggetti. :wink:
Se hai voglia, prova a capire bene come funziona il tutto, cioe’ come sono costruite e cosa fanno le varie istruzioni, comprese quelle di output.
Cerca metodi e proprieta’ nella documentazione.
Dove trovare la documentazione su questi oggetti dovrebbe essere chiaro dal nome completo dei tipi di oggetto, che qui sono delle struct.
Per gli oggetti piu’ semplici RhinoCommon spesso usa le struct anziche’ le classi.
Se non hai ancora studiato le struct, non preoccuparti. Considerale come una classe per ora.
Nello script usiamo anche delle stringhe, per l’output.
Ho cercato di usare cose che in C# non cambino … be’, fino a un certo punto. :blush:

Se vuoi, come esercizio, potresti:

  1. definire 4 punti che siano i vertici di un quadrato
  2. costruire 4 linee partendo dai punti, cioe’ i lati del quadrato
  3. calcolare e stampare la lunghezza del perimetro usando le linee, cioe’ i lati.

Se invece preferisci qualcosa di diverso … dillo … :slight_smile:

import Rhino

def main():
  p1 = Rhino.Geometry.Point3d( 0, 30, 40 )
  p2 = Rhino.Geometry.Point3d.Origin
  print( p1.GetType().ToString() + '  p1  ' + p1.ToString() )
  print( p2.GetType().ToString() + '  p2  ' + p2.ToString() )
  print( p1.DistanceTo( p2 ).GetType().ToString() + 
      '  p1.DistanceTo( p2 )  ' + 
      p1.DistanceTo( p2 ).ToString() )
  ok, p3 = Rhino.Geometry.Point3d.TryParse( '0,60,80' )
  print( p3.GetType().ToString() + '  p3  ' + p3.ToString() )
  print( p3.DistanceTo( p2 ).GetType().ToString() + 
      '  p3.DistanceTo( p2 )  ' + 
      p3.DistanceTo( p2 ).ToString() )
  p4 = Rhino.Geometry.Point3d( Rhino.Geometry.Point3d.Subtract( p1, p3 ) )
  print( p4.GetType().ToString() + '  p4  ' + p4.ToString() )
  l1 = Rhino.Geometry.Line( p1, p4 )
  print( l1.GetType().ToString() + '  l1  ' + l1.ToString() )
  v1 = l1.Direction
  print( v1.GetType().ToString() + '  v1  ' + v1.ToString() )
  print( v1.Length.GetType().ToString() + '  v1.Length  ' + v1.Length.ToString() )
  print( v1.X.GetType().ToString() + '  v1.X  ' + v1.X.ToString() )
  print( v1.Y.GetType().ToString() + '  v1.Y  ' + v1.Y.ToString() )
  print( v1.Z.GetType().ToString() + '  v1.Z  ' + v1.Z.ToString() )

main()
1 Mi Piace
def main1():
    p1 = Rhino.Geometry.Point3d( 0, 0, 0 )
    p2 = Rhino.Geometry.Point3d( 0, 100, 0 )
    p3 = Rhino.Geometry.Point3d( 100, 100, 0 )
    p4 = Rhino.Geometry.Point3d( 100, 0, 0 )
    
    l = []
    l.append(Rhino.Geometry.Line( p1, p2 ))
    l.append(Rhino.Geometry.Line( p2, p3 ))
    l.append(Rhino.Geometry.Line( p3, p4 ))
    l.append(Rhino.Geometry.Line( p4, p1 ))
    
    for i in l:
        scriptcontext.doc.Objects.AddLine(i)
        print(i.Direction.Length.GetType().ToString() + '  i.Length  ' + i.Length.ToString())
    scriptcontext.doc.Views.Redraw()

tra poco vedo di aggiungere la lunghezza. . .
ok modificata, aggiunta seconda riga al for

1 Mi Piace

:+1:

Invece del loop bastava anche:

p = l[ 0 ].Length + l[ 1 ].Length + l[ 2 ].Length + l[ 3 ].Length
print( 'Perimetro = ' + p.ToString() )

Comunque va benissimo come hai fatto.
In piu’ hai pure disegnato le linee utilizzando la ObjectTable:slight_smile:
Imparare a usare le varie ‘Table’ di RhinoCommon e’ fondamentale.
Ti consentono di lavorare con oggetti Rhino, layer, viste ecc.

Bene.

grazie Emilio per l’esempio, comunque se non avevo il tuo esempio non ci sarei riuscito
(sopratutto quello che hai fatto tu)

infatti l’esercizio che avevo in mente di fare era proprio ricercare nell’help
previa tue indicazioni le classi/metodi/proprietà ecc ed andare a costruire
il codice. per dire mi indicavi quali oggetti “vedi in grassetto” sono da usare
e anche sotto quale nomespace andarli a cercare in modo che prendo
confidenza e familiarità coi nomi e distinguere bene un oggetto dall’altro

1 Mi Piace