override e’ una cosa diversa, dovrebbe solo significare che ridefinisci quel metodo in quella classe anziche’ utilizzare il metodo con lo stesso nome definito nella classe madre.
Riguarda le classi derivate, ma non influisce sul fatto che un metodo sia static o meno.
Non c’e’ niente di male a utilizzare metodi static, devi solo richiamarli attraverso la classe anziche’ attraverso un oggetto.
Credevo che con le ultime modifiche lo script funzionasse …
Se non e’ cosi’, dimmi cosa succede.
quelle due righe provengono dalla seconda foto del messaggio 9 che ho postato prima
da quello che ho capito è questo il modo per richiamare il codice usando C# in Rh8
adesso che noto nella terza foto invece dove c’è esempio con i vertici mesh viene utilizzato
anche RhinoDoc.ActiveDoc magari potrebbe essere come indicazione anche in questo caso
Emilio, col tuo 10% paragonadolo al mio 100% stiamo su altri pianeti, io sto imparando (anzi cercando)
tornando al codice, non ho fatto altro che sostituire le 4 righe della classe di default con esempio di C#
inserendo la classe in un namespace (questo non credo faccia differenza) provando ad eseguire il tutto
E’ quello che ti ho detto ieri:
visto che nell’esempio usa RhinoDoc.ActiveDoc, usiamolo anche noi.
Si’, ma hai mischiato il richiamo di un metodo non static, che forse possiamo chiamare instance,
con la definizione di un metodo static.
Ottimo.
Resto dell’idea che servirebbe una conoscenza di base dei concetti della OOP,
tipo sapere cosa sono classi, oggetti, campi, metodi, cosa sone e come si scrivono e si usano i metodi instance e quelli static, un po’ di ereditarieta’
e per C#, anche conoscere proprieta’ e structure, cosa fa override …
e volendo altro ancora. … Ce ne sarebbe da imparare …
tutte ottime osservazioni Emilio, però mettiti anche nei miei panni,
quel poco che ho imparato sul C# lo eseguito nel VS
adesso invece volevo far eseguire i codici in Rh8
prendendo gli esempi di codici C# che già per
eseguirli in VS bisogna modificarli a prescindere
credo che comprendi per chi è all’inizio tutti questi passaggi da un modo di scrivere/eseguire
codici in diversi ambienti faccia uscire il fumo dalle orecchi un po a tutti figuriamoci ai meno pratici.
tornando al problema, se scrivo la sintassi in questo modo:
var main = new Program.Class.**DivideCurveBySegments**(RhinoDoc.ActiveDoc);
mi torna questo problema:
The type name ‘DivideCurveBySegments’ does not exist in the type ‘Class’
mentre cosi:
var main = new Program.Class();
**main**.DivideCurveBySegments(RhinoDoc.ActiveDoc);
mi torna quetsaltro messaggio:
Member ‘Class.DivideCurveBySegments(RhinoDoc)’ cannot be accessed with an instance reference; qualify it with a type name instead
gli asterischi indicano la parti sottolineate come errori
Se vuoi puoi metterci var main =, visto che quel metodo restituisce un risultato,
ma nessun new, se no cambia completamente il significato, come pensavo di aver spiegato …
Ma evidentemente non l’ho fatto …
using System;
using Rhino;
using Rhino.Commands;
using Rhino.Input;
using Rhino.Geometry;
using Rhino.DocObjects;
namespace Program
{
partial class Class
{
public static Result DivideCurveBySegments(RhinoDoc doc)
{
const ObjectType filter = ObjectType.Curve;
ObjRef objref;
var rc = RhinoGet.GetOneObject("Select curve to divide", false, filter, out objref);
if (rc != Result.Success || objref == null)
return rc;
var curve = objref.Curve();
if (curve == null || curve.IsShort(RhinoMath.ZeroTolerance))
return Result.Failure;
var segment_count = 2;
rc = RhinoGet.GetInteger("Divide curve into how many segments?", false, ref segment_count);
if (rc != Result.Success)
return rc;
Point3d[] points;
curve.DivideByCount(segment_count, true, out points);
if (points == null)
return Result.Failure;
foreach (var point in points)
doc.Objects.AddPoint(point);
doc.Views.Redraw();
return Result.Success;
}
}
}
Program.Class.DivideCurveBySegments(RhinoDoc.ActiveDoc);
a quel punto, ho provato anche a togliere la variabile, giusto per… è funziona anche in questo modo.
anche se debbo dirti la verità questa cosa mi ha spiazzato, in passato quando abbiamo trattato l’argomento C# tra le tante cose fu sottolineato ricordo proprio la necessità di dover usare la parola chiave new ma magari era riferito solo per quel contesto. comunque sono contento di questa sintassi, alla fine adesso in questo modo posso ottenere la sintassi di cui io parlai tempo fa comparandolo con Py appunto senza dover chiamare come istanze.
alla fine è nel mio karma, con la testa penso di fare alcune cose,
ma nella pratica le riesco a fare tempo dopo, anzi molto tempo dopo
ps grazie
edit: il metodo senza il public, funziona anche senza namespace e senza la classe. buono a sapersi.
(chissà magari è una possibilità con l’edit di Rh8, può darsi anche che in VS non sia possibile)
acclarato che questo 3d è stato risolto, te la sentiresti di fare, alcune riflessioni su un paio di punti che
non mi sono proprio chiari dal codice originale postato a questo conclusivo e finale con le tue modifiche?
new la usi quando costruisci un oggetto.
Se il metodo e’ statico, visto che c’e’ scritto static, come abbiamo detto va richiamato usando direttamente il nome della classe,
non deve esserci nessun oggetto.
Questa e’ sintassi di base del C#, cerca di ricordarla, dopo averla capita, se vuoi continuare usare il linguaggio senza troppi problemi.
Si’, ho visto (per quel poco che si vede) dagli esempi che hai postato che negli script per Rhino 8 non e’ necessario utilizzare una classe.
Meglio cosi’, secondo me, meno cose da scrivere. Cose che in uno script servono a poco.
Per il poco che so io, chiedi pure !
( Ma forse non riesco a rispondere subito )
infatti in VS se si toglie la Classe manda a quel paese ahahahah
ci mancherebbe
con un breve riepilogo, cercherò di spiegare tutto in modo conciso:
premessa: col VS ho soltanto fatto alcuni esempi base (molto base) da alcuni videi in rete per vedere
la sintassi dei cicli, condizioni, operatori e cose di questo tipo e alcune prove con le Classi e Metodi,
ma in Rhino quei pochi e piccoli script che sono riuscito a fare usando RCommon li ho fatti in Py.
questo giusto per introdurre il quesito che mi serve come paragone tra i due linguaggi per capire:
nelle spiegazioni sul C# fatte tempo addietro, come argomenti nuovi che non avevo mai affrontato,
c’erano l’ereditarietà delle Classi, ma dai miei ricordi e dopo un breve riepilgo, in pratica si eriditano
i membri della Classe tranne i costruttori. e fin qui mi sembra che non ci dovrebbero essere problemi.
mentre in queste righe di esempio di C# ho notato due cose che non ho mai trattato con Py:
public static Result DivideCurveBySegments(RhinoDoc doc)
il Result dopo lo static ed il RhinoDoc doc
credo che l’argomento in questione per il RhinoDoc doc sia questo:
a parte che in questa spiegazione come al solito non ho capito bene cosa voglia dire,
anche perché non sono riuscito nemmeno a mettere in pratica i due esempi elencati.
a parte la mia solita domanda volendo anche da non prendere in considerazione del perché in Py
mancano quei riferimenti, ovviamente sarà per il fatto che appunto funzionano in modo differente.
ma passando al nocciolo, l’unica cosa che riesco ad intuire è che RhinoDoc viene passato nel metodo,
il doc dovrebbe essere tipo abbreviazione tipo as in Py, ma il Result non ne ho proprio idea.
(azzardo nel dire che sarebbe il risultato di RhinoDoc doc con il quale il metodo deve lavorare?)
Intanto mi concentrerei su questo, che e’ importante.
Si riallaccia a quanto dicevo sopra:
Result e’ il tipo di dati restituito dal metodo. RhinoDoc e’ il tipo di dati del parametro di quel metodo.
E in effetti l’avevamo gia’ detto …
L’unica differenza rispeto a Python e’ che in C# devi scrivere i tipi di dati, non solo i nomi.
In Python:
def cubo( num )
return num * num * num
in C#
double cubo( double num )
{
return num * num * num;
}
in C# non scrivi def, al suo posto non si scrive niente.
Pero’ devi scrivere il tipo di dati restituito (il primo double )
e anche i tipi di dati di tutti i parametri richiesti dalla funzione ( qui il secondo double )
doc e’ il nome del parametro che passi al metodo.
come num negli esempi qui sopra.
Per ora mi fermerei qui.
Perche’ finche’ non e’ chiaro questo mi sembra inutile andare avanti.
grazie per la spiegazione, cerco qualche altra info e nel caso ti faccio sapere per i dubbi…
ma debbo trovare un’altra fonte di informazione, il sito pricncipale per quanto i riguarda,
è poco chiaro, lo vedo tipo annotazioni su cose complesse ma per chi già le conosce.
(per chi è all’inizo, e per chi come me non ha una forte base alle spalle non’è indicato)
per l’esempio che ho riportato nell’ultima foto, leggendolo con calma ho capito come eseguirlo:
using System;
SampleRefType.TestRefType();
public class SampleRefType
{
public int value;
public static void TestRefType()
{
SampleRefType rt = new SampleRefType();
rt.value = 44;
//ModifyObject(rt);
Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
obj.value = 33;
}
}
sembra di guardare una matrioska, in pratica com’è riportato il codice stampa TestRefType
altrimenti togliendo i due slash viene stampato il valore del metodo ModifyObject
ragionando su quanto appena scritto quindi (e letto nel link di Microsoft)
il ModifyObject lo posso equiparare all’argomento di questa discussione che hai risolto
mentre invece con TestRefType sarebbe la stessa cosa ma eseguito in modo differente
(vedi che debbo fare, leggendo non visualizzavo, eseguendo il codice ho capito l’esecuzione)
unica cosa diversa e che ModifyObject non ha la parola Result
prima del metodo, ho provato ad inserirlo ma poi mi tornano due errori
Resto della mia idea … secondo me e’ inutile impelagarsi adesso sui valori by reference o by value e cose del genere, se prima non impari le basi.
E temo che non ci siamo ancora, se scrivi questo:
Come ho detto prima, Result e’ il nome di un particolare tipo di dati, non e’ una parola qualsiasi.
In particolare e’ un tipo di RhinoCommon:
Cosa avevo detto ?
I metodi dell’esempio che riporti (che come ho detto per me adesso serve solo a confonderti le idee)
hanno gia’ il loro tipo (ovviamente devono averlo).
Il tipo in questione e’ void … che significa che quei metodi non restituiscono nessun valore.
Infatti dentro non c’e’ nessuna istruzione return.
Non ha senso andare a scrivere un altro tipo di dati, soprattutto se non togli il void.
E non ha senso andare ad aggiungere o togliere parole a caso senza capire cosa si sta facendo.
… A meno che si cerchi un passatempo …
Come dicevo, finche’ non sai le nozioni di base, secondo me questo tipo di esempi ti confonde solo e ti fa perdere tempo.
A mio avviso sarebbe piu’ utile iniziare a fare delle semplici (molto semplici) prove, ad esempio scrivendo una classe e provando a utilizzarla.
Non e’ copiando esempi complessi senza capire che si impara a programmare, e’ provando a scrivere i proprii semplici test e facendoli funzionare. Sempre IMHO, certamente.
Poi ovviamente fai come preferisci, ci mancherebbe …
mi spiace, ma comprendo che le mie domande diano l’impressione di stare più indietro di quanto sia
using System;
using Rhino;
//using Rhino.Commands;
//using Rhino.Input;
//using Rhino.Geometry;
//using Rhino.DocObjects;
static Rhino.Commands.Result DivideCurveBySegments(RhinoDoc doc)
{
const Rhino.DocObjects.ObjectType filter = Rhino.DocObjects.ObjectType.Curve;
Rhino.DocObjects.ObjRef objref;
var rc = Rhino.Input.RhinoGet.GetOneObject("Select curve to divide", false, filter, out objref);
if (rc != Rhino.Commands.Result.Success || objref == null)
return rc;
var curve = objref.Curve();
if (curve == null || curve.IsShort(RhinoMath.ZeroTolerance))
return Rhino.Commands.Result.Failure;
var segment_count = 2;
rc = Rhino.Input.RhinoGet.GetInteger("Divide curve into how many segments?", false, ref segment_count);
if (rc != Rhino.Commands.Result.Success)
return rc;
Rhino.Geometry.Point3d[] points;
curve.DivideByCount(segment_count, true, out points);
if (points == null)
return Rhino.Commands.Result.Failure;
foreach (var point in points)
doc.Objects.AddPoint(point);
doc.Views.Redraw();
Console.WriteLine(doc);
return Rhino.Commands.Result.Success;
}
DivideCurveBySegments(RhinoDoc.ActiveDoc);
in questa versione “diciamo modificata” ho escluso i 4 using per richiamarli ogni volta all’occorrenza,
aggiungere quegli using è stata la prima cosa che ho fatto, che Result non’era a caso ne ero conscio.
se a volte faccio domande strane è perché mi mancano dei tasselli che cerco di collegare,
tieni presente che per ogni domanda che faccio, ce ne sono molte altre che declino nel dire.
(sto cercando di analizzare meglio il codice, se riesco a trarre qualcosa nel caso aggiorno)
Si’, anch’io preferisco in questo modo.
Evito di usare ‘sottintesi’ negli script, preferisco che ogni relazione sia specificata e chiara.
Non sono intelligente abbastanza ( tutt’altro) per poter fare diversamente senza perdermi dei pezzi.
Non preoccuparti di fare domande … a volte mi ‘preoccupo’ io di finire a parlare di cose che raramente serviranno per gli script di Rhino, ma giustamente sei tu che decidi su cosa indagare …
Chiedi pure !
( Al massimo ti rispondo che non lo so neanche io )
A proposito …
Questo esempio dimostra che gli oggetti appartenenti a una classe sono passati alle funzioni come riferimento (il vecchio ByRef del VBScript) e quindi la funzione richiamata puo’ modificare l’oggetto.
Questo non succede con le Structure, che invece vengono passate come valore (ByVal in VBScript).
Il primo metodo TestRefType non richiede nessun parametro, quindi non c’e’ niente da passare ByRef o ByVal.
Il secondo ModifyObject ha come parametro un oggetto appartenente alla classe SampleRefType,
quindi essendo una istanza di classe puo’ solo essere passata ByRef.
Ma questo e’ solo uno dei punti di vista sulla questione …
Se vuoi scavare piu’ a fondo … …
Occhio che l’oggetto di tipo SampleRefType e’ passato ByRef, ma la variabile obj che lo contiene no,
se dentro la funzione assegni un altro oggetto ad obj, fuori dalla funzione questo non avra’ effetto.
Per poter utilizzare la variabile obj in senso ByRef, bisogna dichiararla ref quando defiisci il metodo.
… Almeno se non prendo farfalle …
A quanto ne so, Python funziona allo stesso modo, solo che non ci sono Structure e non puoi dichiarare ref i parametri.
osservazioni: sarà una mia pecca, di avere la testa dura nel farmi entrare le cose, però. . .
using System;
using Rhino;
DivideCurveBySegments();
static Rhino.Commands.Result DivideCurveBySegments()
{
const Rhino.DocObjects.ObjectType filter = Rhino.DocObjects.ObjectType.Curve;
Rhino.DocObjects.ObjRef objref;
var rc = Rhino.Input.RhinoGet.GetOneObject("Select curve to divide", false, filter, out objref);
if (rc != Rhino.Commands.Result.Success || objref == null)
return rc;
var curve = objref.Curve();
if (curve == null || curve.IsShort(RhinoMath.ZeroTolerance))
return Rhino.Commands.Result.Failure;
var segment_count = 2;
rc = Rhino.Input.RhinoGet.GetInteger("Divide curve into how many segments?", false, ref segment_count);
if (rc != Rhino.Commands.Result.Success)
return rc;
Rhino.Geometry.Point3d[] points;
curve.DivideByCount(segment_count, true, out points);
if (points == null)
return Rhino.Commands.Result.Failure;
foreach (var point in points)
RhinoDoc.ActiveDoc.Objects.AddPoint(point);
RhinoDoc.ActiveDoc.Views.Redraw();
Console.WriteLine(RhinoDoc.ActiveDoc);
return Rhino.Commands.Result.Success;
}
con quetsa sintassi il codice funziona ugualmente
ipotizzo che il parametro RhinoDoc doc in quel metodo, sia un residuo di un codice più complesso,
personalmente essendo agli inizi, mi è più leggibile e sopratutto mi sono più chiare le dinamiche
aggiungendo RhinoDoc.ActiveDoc dove necessario, che richiamarlo all’interno del metodo.
static Result DivideCurveBySegments(RhinoDoc doc)
e DivideCurveBySegments(RhinoDoc.ActiveDoc);
in questo modo mi è più vicino e simile agli stessi esempi di codici in Py
from Rhino.DocObjects import *
from Rhino.Input import *
from Rhino.Commands import *
from Rhino.Geometry import *
from Rhino import *
from scriptcontext import doc
def RunCommand():
rc, objref = RhinoGet.GetOneObject("Select curve to divide", False, ObjectType.Curve)
if rc != Result.Success or objref == None:
return rc
curve = objref.Curve()
if curve == None or curve.IsShort(RhinoMath.ZeroTolerance):
return Result.Failure
segment_count = 2
rc, segment_count = RhinoGet.GetInteger("Divide curve into how many segments?", False, segment_count)
if rc != Result.Success:
return rc
curve_params = curve.DivideByCount(segment_count, True)
if curve_params == None:
return Result.Failure
points = [curve.PointAt(t) for t in curve_params]
for point in points:
doc.Objects.AddPoint(point)
doc.Views.Redraw()
return Result.Success
if __name__ == "__main__":
RunCommand()
creo una def/metodo scrivo le istruzioni, e richiamo la def/metodo
senza troppi intrecci vari. (ovviamente quando è possibile evitarli)