C# for Rhino

@0904 capisco che più passa il tempo e meno abbiamo voglia di imparare nuove cose, ma senza un po’ di tempo dedicato significa che vuoi una persona che ti guidi passo passo e ti spieghi: fortuna se la trovi gratis, ma dopo un po’ si stancherà. Anche pagando qualcuno, comunque dovrai fare degli sforzi.
C# ha un rapporto potenziale/tempo di apprendimento molto alto, non fai male se pian piano segui una guida. Devi mettere da parte Rhino per un po’ e fare esercizi, pian piano si capisce.
Non è complicato come sembra, anche se è davvero vastissimo.
Forza, non ci vuole una laurea.
Fai esercizi e posta qui e vediamo insieme.

1 Mi Piace

eeee discorso encomiabile il tuo @luca.filippone

però se non ricordo male è da poco che ti sei laureato. . .

a parte il lato motivazionale (che comunque serve)
tu che hai già iniziato da un bel po, potresti postare qualche tuo esempio anche iniziale di ciò
che hai fatto in tutto questo tempo anche se non si tratta di esempi pratici per Rhino ovviamente. . .

cosi forse, se vedo qualcosa di concreto, mi aiuti a comprendere meglio tutto il discorso fatto no?

Esercizi fatti tanti, ma nessuno conservato e sono gli stessi che trovi nei siti learn Microsoft e di fcamuso. Meglio al contrario, fai qualcosa e dicci cosa non è chiaro, qualcuno saprà darti qualche indicazione.

Quello e’ quando lo usi all’inizio, per dichiarare le librerie o i namespace che intendi usare.
Io parlavo di quello usato in mezzo allo ‘script’.

questo e’ esattamente cosa fa using all’inizio.
E’ un problema scrivere using invece di import ? :wink:

Il namespace credo non sia nemmeno necessario (gli esperti mi correggeranno nel caso) in generale se vuoi utilizzare C#.

Quello che invece credo sia necessario, sempre in generale, e’ usare le classi.
Credo sia l’unica ‘complicazione’ necessaria in piu’ rispetto a Python.
Per questo concordo con te: e’ una cosa in piu’ da utilizzare se vuoi scrivere in C#. :slight_smile: .

Se, legittimamente, non vuoi impegolarti con complicazioni maggiori rispetto a uno script in VBS o in Python, ci vuole Rhino 8.
Non so se tu hai intenzione di passare poi a Rhino 8, o eventualmente di iniziare anche subito a fare qualche prova con la WIP, se hai una licenza Rhino 7…

Per questo, in un’altra discussione, si parlava di cominciare ad esercitarsi con C# in GH.
Li’ c’e’ il componente bell’e pronto, non devi preoccuparti di using o namespace o classi.
Cioe’ le classi le usi ovviamente, quelle di RhinoCommon, ma in genere non sei obbligato a scriverne di nuove.

Anzi, personalmente avevo anche suggerito di imparare prima un po’ il linguaggio lasciando stare Rhino. Mi sembrava piu’ semplice.
Ma anche quell’idea pare non abbia riscosso un grande favore … :wink: :grinning_face_with_smiling_eyes:

Se conti di restare su Rhino 7, l’unico modo per utilizzare il C# (sempre escluso GH) sono i plug-in.
Ma i plug-in non sono mai stati comodi da scrivere come uno script, qualunque linguaggio tu voglia usare.
… E, parere personale, ultimamente la cosa e’ peggiorata … :wink:

In ogni caso, se ho capito bene il primo plug-in sei riuscito a realizzarlo.
Complimenti per questo ! A te e a Sergio. :slight_smile:
A questo punto a mio parere (ma ovviamente non e’ detto che vada bene per te) sarebbe meglio intanto capire bene come funziona quel plug-in, e poi provare a cambiare qualcosa, poco per volta.

Hai capito come funziona il plug-in ?
Cioe’ cosa fanno le varie istruzioni ?
Se no mi sembra inutile cercare di andare avanti …

1 Mi Piace

Emilio hai centrato tutti i punti perfettamente :clap: :clap:

parto dalla fine:

  1. sto cercando proprio di capire cosa posso togliere e cosa posso modificare

  2. è vero che il primo plug-in l’ho realizzato, ma non’é farina del mio sacco
    in pratica (non comprendo come mai) prendo un nuovo progetto col wizar esce un codice in automatico
    alla fine clicco F5/Compila ed in una cartella remota e nascosta mi crea un file RHP che carico in Rhino
    io in pratica non ho fatto proprio nulla (appunto sto cercando di capire cosa fare e come farlo punto 1)
    seguendo i passaggi indicati da Sergio è stato semplice se lo installi anche tu mi farebbe piacere :+1:
    io mi ero inceppato seguendo la guida del 2019 che mi diceva di installare SDK e altre librerie varie
    (ma forse come avevi detto serviva per C/C++)

  3. si infatti adesso l’unica cosa che mi è chiara proprio il fatto che hai accennato tempo fa:
    che con la V8 si possono fare script con il C# in Rh e allora non comprendevo essendo che mi chiedevo ma se già i plug-in si possono scrivere in C# perché è una novità? non sapevo che per scrivere un plug-in in Rhino bisognava installare VStudio e bisogna anche conoscere il suo funzionamento. mentre invece avere la possibilità di sciptare in C# direttamente in Rhino come si fa con VBS/Py di sicuro è tutt’altra cosa.

  4. usare C# di Gh si infatti anche a me inizialmente mi sembrava una buona idea ma il mio intendo era però quello di inserire i codici per eseguire i metodi che servono in Rhino questi per intenderci:
    https://developer.rhino3d.com/api/RhinoCommon/html/R_Project_RhinoCommon.htm
    ma ovviamente in Gh non credo che vada bene essendo che come in Py ci sono i riferimenti
    agli input mentre il codice postato invece si deve cliccare sugli oggetti ecc
    (poteva andare bene come dici per usare C# in generale, ma sarebbero stati esempi non per Rhino)

questo ancora adesso non l’ho capito, mi spiego: se ricordo bene RhinoCommon è scritto in C
però mi servono le classi scritte in RhinoCommon per scrivere il codice in C#? ? ? :woozy_face: :dizzy_face: :face_with_spiral_eyes:

anch’io avevo pensato che potevo togliere il NameSpace anche se a dire il vero è l’unica cosa che in fin dei conti non mi da fastidio più di tanto e ovviamente non’é un problema nemmeno usare using al posto di from/import, quello che mi snervano sono quei 3 / 4 public che debbo capire il funzionamento.

tanto per fare un esempio:

partial class Examples
{
  public static Rhino.Commands.Result AddCircle(Rhino.RhinoDoc doc)
  {
    Rhino.Geometry.Point3d center = new Rhino.Geometry.Point3d(0, 0, 0);
    const double radius = 10.0;
    Rhino.Geometry.Circle c = new Rhino.Geometry.Circle(center, radius);
    if (doc.Objects.AddCircle(c) != Guid.Empty)
    {
      doc.Views.Redraw();
      return Rhino.Commands.Result.Success;
    }
    return Rhino.Commands.Result.Failure;
  }
}

questo codice preso dalla guida online dovrebbe creare un cerchio

namespace MyRhinoPlugin3
{
    public class MyRhinoPlugin3Command : Command
    {
        public MyRhinoPlugin3Command()
        {
            // Rhino only creates one instance of each command class defined in a
            // plug-in, so it is safe to store a refence in a static property.
            Instance = this;
        }

        ///<summary>The only instance of this command.</summary>
        public static MyRhinoPlugin3Command Instance { get; private set; }

        ///<returns>The command name as it appears on the Rhino command line.</returns>
        public override string EnglishName => "MyRhinoPlugin3Command";

        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            // TODO: start here modifying the behaviour of your command.
            // ---

lasciando il namespace

partial class Examples

questa stringa dovrebbe sostituire

public class MyRhinoPlugin3Command : Command

ma se ho capito bene : Command deve rimanere

public static Rhino.Commands.Result AddCircle(Rhino.RhinoDoc doc)

e questa dovrebbe sostituire

public static MyRhinoPlugin3Command Instance { get; private set; }

poi c’é:

public override string EnglishName => "MyRhinoPlugin3Command";

che da come ho letto la traduzione nella guida serve per il comando in inglese o una cosa simile

protected override Result RunCommand(RhinoDoc doc, RunMode mode)

ed in fine c’é protected override che non so a cosa serva

      return Rhino.Commands.Result.Success;
    }
    return Rhino.Commands.Result.Failure;

a parte il fatto che il codice C# per creare un cerchio ha due return

comunque ho provato varie modifiche ma mi da alcuni errori vari da verificare. . .

Obbligatorio direi. Serve a definire le scope delle classi.

Wow, ho la wip, quindi potrei provare. :+1:t3::grin:

Qui ne avevamo parlato

Una variabile public può essere vista da tutte le classi che appartengono allo stesso namespace.
Private, di default, sono leggibili solo dentro lo scope di dichiarazione, le protected sono leggibili dalla classi derivate, l override consente di implementare le classi virtual, la classe static viene instanziata subito in memoria e non necessita di implementazione,…

Ma non si fa prima a leggere qualcosa?
:person_shrugging:t2:

Copi solo questo codice all’interno del metodo RunCommand.

Inoltre, visto che nel file .cs viene dichiarato
using Rhino.Commands;
using Rhino.Geometry;

il codice si semplifica così:

    Point3d center = new Point3d(0, 0, 0);
    const double radius = 10.0;
    Circle c = new Circle(center, radius);
    if (doc.Objects.AddCircle(c) != Guid.Empty)
    {
      doc.Views.Redraw();
      return Result.Success;
    }
    return Result.Failure;

Più semplice di così …

2 Mi Piace

mi sa che sono partito troppo scoraggiato

            // TODO: start here modifying the behaviour of your command.
            // ---
 

            // ---
            return Result.Success;

Sergio lo avevo fatto come prima tentativo il suggerimento che mi hai dato
solo che avevo rimasto l’ultima riga return Result.Success; essendo che all’inizio come avevi indicato l’altra volta dalla scritta: TODO: start here modifying the behaviour of your command. inizia il codice.
quindi mi ero tenuto all’interno delle // - - - // mentre invece bisogna cancellarlo :man_facepalming: :man_facepalming: :man_facepalming:

potevano scriverlo anche cosi forse sarebbe stato più chiaro:

            // TODO: start here modifying the behaviour of your command.
            // ---
 

            return Result.Success;
            // ---

oppure potevo insistere e sovrascrivere anche l’ultima riga

ps si per le semplificazioni pian piano, comunque cambiando il codice si cambiano anche gli
using in automatico da utilizzare using Rhino.Commands; using Rhino.Geometry;

quindi se con gli using vengono richiamate all’inizio del codice, dopo non serve scrivere Rhino.Geometry

ottimo a saperlo :+1:

Per questo adesso devi capire cosa fa il plug-in, prima di modificarlo.

Il link punta alla documentazione di RhinoCommon.
Non capisco cosa intendi … :confused:

Scusa, per cosa non va bene GH ? :slight_smile:
E di quale codice postato parli ? Quello del plug-in che hai postato prima ?

Certo un plug-in lavora diversamente da GH, ma proprio per questo sperimentare in GH e’ piu’ semplice. Non devi preoccuparti degli input dall’utilizzatore.
Puoi concentrarti sulla geometria, ad esempio.

A quanto ne so, RhinoCommon e’ scritto in C#, e in ogni caso e’ una libreria per C#.
E’ l’unico modo di interagire con Rhino usando il C#.
Se non usi RhinoCommon, come fai, ad esempio, a dire a Rhino di disegnare un cerchio ?

Te ne ha parlato Luca.
E’ una cosa tipica della programmazione ad oggetti: certi dati e certe funzioni li puoi utilizzare da alcune ‘zone’ del programma, ma non da altre.
Luca ha elencato le regole, ma tutto cio’ riguarda solo l’utilizzo di quella determinata classe o funzione o altro.
Non modifica i valori dei dati o il funzionamento delle istruzioni.
Non preoccupartene piu’ di tanto per ora.
public di solito vuol solo dire che quella cosa si puo’ usare liberamente, quindi in pratica per quanto ti riguarda non aggiunge nessuna informazione. :grinning_face_with_smiling_eyes:
Da questo punto di vista, in Python sarebbe tutto public. :grinning:

Credo che quello che disegna il cerchio sia qualche riga piu’ sotto …
Cioe’ siano le istruzioni scritte nel metodo RunCommand() , di cui vediamo solo l’inizio.

E che problema ti da’ ?
Mi sembra che uno sia dentro una if e l’altro fuori.
Se la condizione della if e’ vera restituiamo un valore, se no ne restituiamo un altro.
Cosa c’e’ di strano ? :slight_smile:

Scusa, non capisco il senso di queste sostituzioni … e non capisco nemmeno cosa vuoi sostituire con cosa … :confused: :grinning_face_with_smiling_eyes:

Scusa se mi ripeto, ma hai capito cosa fanno le istruzioni del metodo RunCommand() ?
E’ li’ dentro che dici a Rhino cosa deve fare.
Lo dice anche il commento:

// TODO:  start here modifying the behaviour of your command.
// ---

Cioe’ sono quelle le istruzioni del tuo plug-in.

che quello dichiarato public si possa richiamare liberamente su questo ci arrivo è uguale anche in VBS
quello che volevo intendere è capire cosa indica le strighe successive a public tipo:

public static MyRhinoPlugin3Command Instance { get; private set; }

mi sembra tipo i byref / byval che ne parlammo alcuni giorni fa qui invece c’é istance get e private set

ma se il Common è una libreria che serve per far dialogare Rhino con il linguaggio C#
quindi è come la libreria di rhinoscriptsyntax che serve per far dialogare Rhino con Py
ma a questo punto perché con Py/Common non posso fare le stesse cose di C#/Common?

se come codice lasciavo solo il commento a quel punto anche VStudio mi avrebbe mandato a quel paese
ahahahah :rofl: :rofl: :joy:

quello che intendevo era di dover inserire il codice nell’intermezzo tra gli slash iniziale e finale

E’ una proprieta’ (property) di quella classe.
static significa che esiste un valore unico per tutta la classe, non uno per ogni oggetto.
Serve per leggere (get) o settare (set) il valore di quella proprieta’.
Di questa parte del plug-in ha parlato Sergio sopra:

Ovviamente questa parte non va toccata.

Per quanto ne so, puoi fare le stesse cose.

I commenti puoi lasciarli o meno.
L’importante e’ aggiungere le istruzioni per far lavorare il plug-in.

Mi sembra di essere ritornati a molti mesi fa … forse anche più di un anno fa!
Di seguito un link alla guida API rhinocommon con esempio in c# e sotto in py.

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

Senza entrare nel merito del metodo trattato, mi sembra evidente che i due codici sono identici
(al netto delle specifiche legate al linguaggio)!

Pertanto confermo in toto quanto affermato da @emilio.

Eh … il forum mantiene giovani !
:wink:

… In effetti capita abbastanza spesso di continuare a ripetere le stesse cose …
:grinning_face_with_smiling_eyes:

2 Mi Piace

altro step fatto:
in pratica in un progetto (creazione di un plug-in quindi un solo file RHP)
ho verificato come inserire più comandi, e una volta caricato il file in Rh
e digitalizzando il nome del comando desiderato mi richiama quel codice
nel primo comando eseguiva la creazione della retta, nel secondo la creazione del cerchio

giusto quanto detto, ma se non erro, in molti altri metodi ci sono solo esempi C# e VB mentre manca Py

1 Mi Piace

Basta cercare nel posto giusto.

Se sei in grado di replicare tutti questi esempi riesci a fare di tutto.

scusa se insisto ma in altri 3d mi si è sempre invogliato a passare al C# per poter fare più cose
anche nel forum internazionale sottolineano la differenza se si scrive codici con diversi linguaggi

di sicuro ci sarà una spiegazione ma in quest’altro link vengono menzionati solo C# e VB
poi chissà forse queste proprietà/metodi/eventi si possono usare anche in Py non saprei

ho iniziato a seguire i tutorial su C# di fcamuso su yt
(non per spezzare una lancia a mio favore)

ma proprio al primo video, ha sottolineato che con la versione VStudio Code 2019 in Windows
(quella da me installata tempo fa che non sono riuscito ad utilizzare) può dare dei problemi
e che se reinstallandolo non si risolveva, lui consigliava di installare VStudio Community
la versione da installare indicata da Sergio. che dire. . . sono una calamita dei BUG :joy:

ps ogni tanto quel fischiariello eeee

Come ha gia’ detto anche Sergio, RhinoCommon la puoi usare anche con Python.

Sui vari linguaggi ognuno ha le sue opinioni e le sue preferenze.

Personalmente penso che usando RhinoCommon con Python talvolta ci si puo’ trovare in situazioni in cui non e’ proprio comodissimo utilizzare una libreria scritta per C# con Python, dato che tra i due linguaggi ci sono delle differenze.

Poi probabilmente per altri questo problema (o problemino se vuoi) non esiste.

Diciamo anche che per capire bene come utilizzare RhinoCommon in Python, secondo me un poco il C# devi conoscerlo, dato che le varie classi ecc. sono classi C#, scritte per C#, quindi per capire bene come funzionano un po’ di C# non guasta … :wink:

Ma questa e’ solo la mia idea.
Altri la penseranno certamente in maniera diversa … :slight_smile:

In ogni caso, se (prima o poi) volessi provare a usare RhinoCommon in uno script Python, chiedi pure.
Ma stai sicuro che quello che impari di RhinoCommon esercitandoti con C# ti sara’ certamente molto utile anche per un eventuale utilizzo con Python, quindi quello che stai facendo non e’ assolutamente una perdita di tempo, qualunque linguaggio tu decida di utilizzare in futuro.

3 Mi Piace

pienamente daccordo :+1:

infatti è stato anche questo uno dei motivi di iniziare questo percorso

comunque grazie per i tutorial di fcamuso (è vero che già lo conoscevo)
ma questa lista di C# è particolare mi sa che avrei dovuto vederla molto prima
essendo che già dall’inizio tanti discorsi spiega argomenti che abbiamo trattato tempo fa

ps in genere gli altri tutorial spiegavano come usare comandi/metodi ecc questo invece spiega i problemi.

1 Mi Piace

non ho provato con un plug-in per Rh, anche senza namespace ma soltanto con la classe funziona.

ps ma poi hai provato a fare script col C# in Rhino?