Mah … a me sembra piu’ una tendenza a voler modificare le cose senza preoccuparsi prima di capire come funzionano.
Ma ognuno ha i suoi modi di sperimentare …
Se il problema e’ usare una variabile globale anziche’ una locale, si risolve in fretta.
Ma non facendo come nel tuo esempio, perche’ …
… qui dice: continue to use the same doc after the first call to ActiveDoc.
Cioe’ dice di richiamare una sola volta la proprieta’ AtciveDoc e in seguito usare il valore ottenuto da quell’unica chiamata.
(Almeno e’ quello che capisco, perche’ non mi sembra chiarissimo, probabilmente non capisco bene la frase in inglese)
In pratica dice: chiama ActiveDoc all’inizio dello script, salva il valore ottenuto in una variable e in seguito usa quella variabile.
Che poi e’ esattamente quello che si vede nell’esempio che avevi postato.
Io copierei quello che fa l’esempio di McNeel.
… Se per te i parametri delle funzioni sono intrecci … OK.
EDIT:
Se guardi dentro scriptcontext, c’e’ questo:
'''The Active Rhino document (Rhino.RhinoDoc in RhinoCommon) while a script
is executing. This variable is set by Rhino before the exection of every script.
'''
doc = None
Dove dice che Rhino inizializza doc prima di eseguire lo script.
In pratica fa quello che fa l’esempio C# che abbiamo visto sopra.
senza riuscirci, ma forse con le poprietà questo non’è possibile. . .
vabbè intreccio non era riferito al parametro in se per se, ma nel senso, perché richiamarlo dal metodo. . .
non per discolparmi:
avevo semplificato la situazione, ma se non si può fare, seguo le regole che meglio come mi hai cosigliato
(ma preferisco come nella foto che hai rigirato )
(giusto per domistrare che i tuoi consigli non vengono persi)
mentre prima ti rispondevo, pensavo a come modificare il codice con le nuove info a disposizione:
using System;
using Rhino;
var main = new Program();
main.DivideCurveBySegments();
class Program
{
public RhinoDoc doc = RhinoDoc.ActiveDoc;
public 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)
doc.Objects.AddPoint(point);
doc.Views.Redraw();
Console.WriteLine(doc);
return Rhino.Commands.Result.Success;
}
}
Credo sia semplicemente una routine generica, che va bene sia per i plug-in, sia per GH, sia per gli script.
In alcuni di questi casi, se non erro, il valore RhinoDoc e’ predifinito da Rhino, quindi e’ comodo poterlo usare come parametro per la routine principale dello script in quell’esempio.
Andando a naso (ma posso sbagliare) …
Credo che con using si possano importare solo i namespace, non le classi.
In questo caso Rhino e’ un namespace, ma RhinoDoc e’ una classe.
Dai, era una battuta … ma intendevo consigliare di abituarsi a usare i parametri delle funzioni.
In uno script breve non cambia niente, ma scrivendo cose piu’ lunghe solitamente (e personalmente concordo) e’ considerato un buon sistema per evitare possibili confusioni.
invece di optare per la soluzione indicata inizialmente, utilizzando RhinoDoc.ActiveDoc come parametro
using System;
using rh = Rhino;
DivideCurveBySegments(rh.RhinoDoc.ActiveDoc);
static rh.Commands.Result DivideCurveBySegments(rh.RhinoDoc doc)
essendo che, ho il dubbio nel chiamare DivideCurveBySegments(rh.RhinoDoc.ActiveDoc);
in questo modo non sia la stessa cosa dell’esempio nella foto appena postata con la classe.
probabilmente mi sbaglio ma:
public RhinoDoc doc = RhinoDoc.ActiveDoc;
in questo modo associo a doc il RhinoDoc.ActiveDoc e poi il doc viene richiamato di volta in volta.
mentre il questo modo:
DivideCurveBySegments(rh.RhinoDoc.ActiveDoc);
chiamo direttamente all’inizio il RhinoDoc.ActiveDoc
Diciamo che usare una variabile (o un campo, essendo dentro una classe) va bene in tutti i casi, anche se dovessi richiamare la routine principale piu’ volte.
Nel caso specifico, visto che DivideCurveBySegments viene richiamata una volta sola, mi sembra che il funzionamento sia analogo.
In ogni caso usare una variabile apposita male non fa e la puoi prendere come abitudine per tutti gli script C#.
Si’, mi sembra la soluzione migliore .
Quindi la classe ti serve per poter scrivere la funzione DivideCurveBySegments ?
Suppongo di si’ …
Non so come funzioni l’ambiente per gli script C# di Rhino.
Se provi a scrivere la funzione senza racchiuderla in una classe ti da’ errore ?
Resta solo da vedere se la funzione ‘vede’ le variabili definite fuori, cosi’ puoi utilizzare la tua bella variabile doc senza dover usare classi ( … se funziona )
Poi se vuoi usare una classe, niente di male, usala pure …
E’ solo curiosita’ …
Una cosa cosi’ che fa ?
using System;
using rh = Rhino;
RhinoDoc doc = RhinoDoc.ActiveDoc;
DivideCurveBySegments();
static rh.Commands.Result DivideCurveBySegments()
{
// ...
foreach (var point in points)
doc.Objects.AddPoint(point);
doc.Views.Redraw();
Console.WriteLine(doc);
// ...
}
La funzione DivideCurveBySegments non cambia, perde solo il parametro.
Lo hai aggiunto tu il WriteLine ?
Cosa stampa ?
… qualcosa come … “oggetto Rhino.RhinoDoc” ?
E’ un test per provare a non usare classi … una cosa stupida se vuoi …
Giusto, la funzione e’ dichiarata statica …
Se dichiariamo statica anche la variabile ?
static RhinoDoc doc = rh.RhinoDoc.ActiveDoc;
Oppure togliere lo static dalla funzione
using System;
using Rhino;
RhinoDoc doc = RhinoDoc.ActiveDoc;
DivideCurveBySegments();
Commands.Result DivideCurveBySegments()
{
// ...
foreach (var point in points)
doc.Objects.AddPoint(point);
doc.Views.Redraw();
Console.WriteLine(doc);
// ...
}
Scusa eh, non voglio farti perder tempo.
Se vuoi, prova poi con calma, se no fa lo stesso.
E’ solo curiosita’ per capire se c’e’ modo di fare gli script senza classi.
Che poi con o senza non cambia niente …
L’errore era stato mio, dovevo toglierlo subito lo static.
Fuori da una classe non ha senso.
Poi probabilmente Rhino incapsula tutto lo script in una classe nascosta, ma noi non la vediamo e non dobbiamo preoccuparcene.
OK, da tutto cio’ sappiamo che:
Puoi fare come ti pare con gli script.
O usare una classe o non usarla.
Poi per script complessi potrebbe essere comodo usare anche piu’ di una classe.
Ma per quelli semplici possiamo anche decidere di non usarne.
“Usarne” nel senso di scrivere nuove classi.
Le classi .NET e RhinoCommon le useremo regolarmente.
anch’io avevo pensato a questo che hai detto. . .
non so se ricordi, un po di tempo fa, parlammo di una cosa simile, ma inerente a Py sempre di Rhino,
dove io feci alcune domande sul funzionamento di questa stringa di codice if __name__ == "__main__":
ipotizzando che main, potrebbe essere il nome del foglio bianco di un livello superiore di Py in Rh
in pratica, il foglio bianco di Py in Rhino (che non vediamo) avrebbe di default il nome main
la stessa cosa con C#, e se analizziamo la regola in VS dove per avviare un codice si è obbligati a creare in una classe, un metodo di nome Main statica, e questo metodo viene avviato per eseguire il tutto.
Questo indica se lo script e’ stato lanciato direttamente (ad esempio da EditPythonScript o da un pulsante)
o se invece e’ un modulo caricato da uno script diverso.
Credo serva per poter testare facilmente un modulo senza interferire col suo uso da modulo esterno.