Discussioni utente:Tek3327/Sandbox

Introduzione

modifica

OpenSCAD è un programma di modellazione solida che si basa su un linguaggio di programmazione funzionale utilizzato per creare modelli che vengono visualizzati in anteprima sullo schermo ed in seguito renderizzato in una mesh 3D, che consente la realizzazione di un modello da esportare in una varietà di formati di file 2D/3D .

Per creare modelli 2D o 3D utilizzando OpenSCAD si deve realizzare uno script di istruzioni.

 object();
 variable = value;
 operator()   action();
 operator() { action();    action(); }
 operator()   operator() { action(); action(); }
 operator() { operator()   action();
              operator() { action(); action(); } }
Objects

Objects sono i blocchi costruttivi per i modelli, creati con le funzioni primitive 2D/3D.

Actions

Actions terminano con un punto e virgola ';'. Essi includono la creazione di oggetti utilizzando primitive e l'assegnazione di valori alle variabili.

Operators

Gli Operators non finiscono con un punto e virgola ';'. Gli operatori, o trasformazioni, modificano la posizione, il colore e altre proprietà degli oggetti. Gli Operators utilizzano parentesi graffe '{}' quando il loro campo di applicazione comprendono più di un'azione. Più di un operatore può essere utilizzato per la stessa azione o gruppo di azioni. Operatori multipli sono eseguiti da destra a sinistra, cioè, l'operatore più vicino all'azione viene elaborato per primo.

 Examples
  
   cube(5);
   x = 4+y;
   rotate(40) square(5,10);
   translate([10,5]) { circle(5); square(4); }
   rotate(60) color("red") { circle(5); square(4); }
   color("blue") { translate([5,3,0]) sphere(5); rotate([45,0,45]) { cylinder(10); cube([5,6,7]); } }

Commenti

modifica

I commenti sono un modo di lasciare note all'interno dello script (sia per se stessi che per i futuri programmatori) descrivendo come funziona il codice, o ciò che fa. I commenti non vengono valutate dal compilatore e non devono essere utilizzati per descrivere il codice che di per se' sia già evidente.

Comments are a way of leaving notes within the script, or code, (either to yourself or to future programmers) describing how the code works, or what it does. Comments are not evaluated by the compiler, and should not be used to describe self-evident code.

OpenSCAD usa commenti in stile C++:

// Questo è un commento
  
myvar = 10; // Il resto della linea è un commento
  
/*
   I commenti multi-linea
   possono essere disposti su più linne.
*/

Valori e tipi di dati

modifica

Un valore in OpenSCAD è un numero (come il 42), un valore booleano (come vero), una stringa (come "testo"), un vettore (come [1,2,3]), oppure il valore indefinito (undef). I valori possono essere memorizzati in variabili, passati come argomenti a funzioni, e restituiti come risultati di funzione.

[OpenSCAD è un linguaggio tipizzato in modo dinamico con un gruppo fisso di tipi di dati. Non ci sono tipi nominati o tipi definiti dall'utente. Le funzioni non sono valori. In effetti, variabili e funzioni occupano namespaces disgiunti.]

I numeri sono il tipo più importante di valore in OpenSCAD, e sono scritte nella notazione decimale utilizzato in altre lingue. Ad esempio, -1, 42, 0.5, 2.99792458e + 8. [OpenSCAD non supporta notazione ottale o esadecimale per i numeri.]

In aggiunta ai numeri decimali, sono definiti i seguenti nomi per i numeri speciali:

  • PI

OpenSCAD ha solo un unico tipo di numero, che è un numero a virgola mobile IEEE a 64 bit. [OpenSCAD non distingue interi e numeri in virgola mobile come due tipi diversi, né supporta i numeri complessi.] A causa dell'utilizzo dello standard IEEE per i numeri in virgola mobile, ci sono alcune differenze dal comportamento dei numeri in matematica:

  • Usiamo virgola mobile binaria. Un numero frazionario non è rappresentato esattamente a meno che il denominatore sia una potenza di 2. Ad esempio, 0,2 (2/10) non ha una rappresentazione interna esatta, ma 0,25 (1/4) e 0,125 (1/8) sono rappresentati esattamente .
  • Il più grande numero rappresentabile è di circa 1e308. Se un risultato numerico è troppo grande, allora il risultato può essere infinito (stampato come Inf echo).
  • Il numero rappresentabile più piccolo è di circa -1e308. Se un risultato numerico è troppo piccolo, allora il risultato può essere -infinity (stampato come -inf dalla eco).
  • Se un risultato numerico non è valido, allora il risultato può essere non un numero (stampato come nan da ECHO).
  • Se un numero non nullo è troppo vicino allo zero per essere rappresentabile, allora il risultato sarà -0 se il risultato è negativo, altrimenti sarà 0. Zero (0) e zero negativo (-0) sono trattate come due numeri distinti per alcune delle operazioni matematiche, e sono stampate in modo diverso da 'echo', anche se risultano uguali.

Si noti che 'inf' e 'nan' non sono supportati come costanti numeriche in OpenSCAD, anche se è possibile calcolare i numeri che sono stampati in questo modo da 'echo'. È possibile definire variabili con questi valori utilizzando:  inf = 1e200 * 1e200;  nan = 0/0;  echo(inf, nan);

Si noti che 'nan' è l'unico valore OpenSCAD che non è uguale a qualsiasi altro valore, compreso se stesso. Anche se è possibile verificare se una variabile 'X' ha il valore indefinito con 'x == undef', non è possibile utilizzare 'x == 0/0' per verificare se x non è un numero. Invece, è necessario utilizzare 'x! = x' per verificare se x è nan.

Valori Booleani

modifica

I Boolean sono valori di verità. Ci sono due valori booleani, vale a dire true e false . Un valore booleano viene passato come argomento di istruzione condizionale 'if()'. operatore condizionale '? : ', e operatori logici '!' (not), '&&' (and), e '||' (or). In tutti questi contesti, si può effettivamente passare qualsiasi quantità. La maggior parte dei valori sono convertiti in 'true' in un contesto booleano, i valori che contano come 'false' sono:

  • falso
  • 0 e -0
  • ""
  • []
  • undef

Si noti che "false" (la stringa), [0] (un vettore numerico), [ [] ] (un vettore contenente un vettore vuoto), [false] (Un vettore contenente il valore booleano false) e 0/0 (Not A Number) valgono tutti true.

Stringhe

modifica

Una stringa è una sequenza di zero o più caratteri Unicode. I valori stringa vengono utilizzati per specificare i nomi dei file durante l'importazione di un file, e per visualizzare il testo a scopo di debug quando si utilizza echo (). Le stringhe possono essere utilizzate anche con il new text() primitive aggiunto nel '2015,03' .

Una stringa letterale è scritta come una sequenza di caratteri racchiusi tra virgolette ", come il seguente: "" (una stringa vuota), o "questa è una stringa".

Per includere un " in una stringa, utilizzare \".Per includere un \ in una stringa, utilizzare \\. Le seguenti sequenze di escape che iniziano con \ possono essere utilizzate all'interno delle stringhe:

  • \ "→"
  • \\ → \
  • \t → tab
  • \n → nuova linea
  • \r → ritorno a capo
  • \u03a9 → Ω - vedere text() per ulteriori informazioni sui caratteri Unicode

Nota: Questo comportamento è stato introdotto dalla versione OpenSCAD-2011.04. È possibile aggiornare i vecchi file utilizzando il seguente comando: sed 's / \\ / \\\\ /' non escaped.scad> escaped.scad

 Esempi:
  
 echo("The quick brown fox \tjumps \"over\" the lazy dog.\rThe quick brown fox.\nThe \\lazy\\ dog.");
  
 nuovo risultato
ECHO: "The quick brown fox jumps "over" the lazy dog. The quick brown fox. The \lazy\ dog." vecchio risultato ECHO: "The quick brown fox \tjumps \"over\" the lazy dog. The quick brown fox.\nThe \\lazy\\ dog."

Intervalli

modifica

Gli intervalli sono utilizzati da for() loops e children(). Hanno due forme:

[<start>:<end>]
[<start>:<increment>:<end>]

Anche se racchiusi tra parentesi quadre [], non sono vettori. Usano due punti : per separare anziché virgole.

r1 = [0:10];
r2 = [0.5:2.5:20];
echo(r1); // ECHO: [0: 1: 10]
echo(r2); // ECHO: [0.5: 2.5: 20]

Si dovrebbe evitare di valori passo che non possono essere rappresentati esattamente come numeri binari in virgola mobile. Gli interi vanno bene, così come i valori frazionari il cui denominatore sia una potenza del due. Ad esempio, 0,25 (1/4) e 0,125 (1/8) vanno bene, mentre 0,2 (2/10) andrebbe evitato. Il problema con questi valori è che la vostra gamma potrenne avere troppi o troppo pochi elementi, a causa di aritmetica inesatta.

Un mancante < increment> è posto pari a 1 per default. Un intervallo nella forma [<start>:<end>] con < start> maggiore di <end> genererà un avvertimento ed è equivalente a [<end' '>:1:<start>]. Una intervallo nella forma [<start>: 1: <end>] con <start> maggiore di <end> non genera un messaggio di avviso ed è equivalente a []. Il <increment> in un intervallo può essere negativo (per le versioni dopo il 2014).

The Undefined Value

modifica

The undefined value is a special value written as undef. It's the initial value of a variable that hasn't been assigned a value, and it is often returned as a result by functions or operations that are passed illegal arguments. Finally, undef can be used as a null value, equivalent to null or NULL in other programming languages.

All arithmetic expressions containing undef values evaluate as undef. In logical expressions, undef is equivalent to false. Relational operator expressions with undef evaluate as false except for undef==undef which is true.

Note that numeric operations may also return 'nan' (not-a-number) to indicate an illegal argument. For example, 0/false is undef, but 0/0 is 'nan'. Relational operators like < and > return false if passed illegal arguments. Although undef is a language value, 'nan' is not.

Variables

modifica

OpenSCAD variables are created by a statement with a name or identifier, assignment via an expression and a semicolon. The role of arrays, found in many imperative languages, is handled in OpenSCAD via vectors.

var = 25;
xx = 1.25 * cos(50);
y = 2*xx+var;
logic = true;
MyString = "This is a string";
a_vector = [1,2,3];
rr = a_vector[2];      // member of vector
range1 = [-1.5:0.5:3]; // for() loop range
xx = [0:5];            // alternate for() loop range

OpenSCAD is a Functional programming language, as such variables are bound to expressions and keep a single value during their entire lifetime due to the requirements of referential transparency. In imperative languages, such as C, the same behavior is seen as constants, which are typically contrasted with normal variables.

In other words OpenSCAD variables are more like constants, but with an important difference. If variables are assigned a value multiple times, only the last assigned value is used in all places in the code. See further discussion at Variables are set at compile-time, not run-time. This behavior is due to the need to supply variable input on the command line, via the use of -D variable=value option. OpenSCAD currently places that assignment at the end of the source code, and thus must allow a variables value to be changed for this purpose.

The variable retains its last assigned value at compile time, in line with Functional programming languages. Unlike Imperative languages, such as C, OpenSCAD is not an iterative language, as such the concept of x = x + 1  is not valid, get to understand this concept and you will understand the beauty of OpenSCAD.

Before version 2015.03

It was not possible to do assignments at any place except the file top-level and module top-level. Inside an if/else  or for  loop, assign() was needed.

Since version 2015.03

Variables can now be assigned in any scope. Note that assignments are only valid within the scope in which they are defined - you are still not allowed to leak values to an outer scope. See Scope of variables for more details.

a=0;
if (a==0) 
  {
 a=1; //  before 2015.03 this line would generate a Compile Error
      //  since 2015.03  no longer an error, but the value a=1 is confined to within the braces {}
  }

Undefined variable

modifica

A non assigned variable has the special value undef. It could be tested in conditional expression, and returned by a function.

 Example
  
 echo("Variable a is ", a);                // Variable a is undef
 if (a==undef) {
   echo("Variable a is tested undefined"); // Variable a is tested undefined
 }

Scope of variables

modifica

When operators such as translate() and color() need to encompass more than one action ( actions end in ; ), braces {} are needed to to group the actions, creating a new, inner scope. When there is only one semicolon, braces are usually optional.

Each pair of braces creates a new scope inside the scope where they were used. Since 2015.03, new variables can be created within this new scope. New values can be given to variables which were created in an outer scope . These variables and their values are also available to further inner scopes created within this scope, but are not available to any thing outside this scope. Variables still have only the last value assigned within a scope.

                       // scope 1
 a = 6;                // create a
 echo(a,b);            //                6, undef
 translate([5,0,0]){   // scope 1.1
   a= 10;
   b= 16;              // create b
   echo(a,b);          //              100, 16   a=10; was overridden by later a=100;
   color("blue") {     // scope 1.1.1
     echo(a,b);        //              100, 20
     cube();
     b=20;
   }                   // back to 1,1
   echo(a,b);          //              100, 16
   a=100;              // override a in 1.1
 }                     // back to 1   
 echo(a,b);            //                6, undef
 color("red"){         // scope 1.2
   cube();
   echo(a,b);          //                6, undef
   }                   // back to 1
 echo(a,b);            //                6, undef
  
 //In this example, scopes 1 and 1.1 are outer scopes to 1.1.1 but 1.2 is not.
Anonymous scopes are not considered scopes:
 {
   angle = 45;
 }
 rotate(angle) square(10);

For() loops are not an exception to the rule about variables having only one value within a scope. A copy of loop contents is created for each pass. Each pass is given its own scope, allowing any variables to have unique values for that pass. No, you still can't do a=a+1;

Variables are set at compile-time, not run-time

modifica

Because OpenSCAD calculates its variable values at compile-time, not run-time, the last variable assignment, within a scope will apply everywhere in that scope, or inner scopes thereof. It may be helpful to think of them as override-able constants rather than as variables.

// The value of 'a' reflects only the last set value
   a = 0;
   echo(a);  // 5
   a = 3;
   echo(a);  // 5
   a = 5;

While this appears to be counter-intuitive, it allows you to do some interesting things: For instance, if you set up your shared library files to have default values defined as variables at their root level, when you include that file in your own code, you can 're-define' or override those constants by simply assigning a new value to them.

Special Variables

modifica

Special variables provide an alternate means of passing arguments to modules and functions. All variables starting with a '$' are special variables, similar to special variables in lisp. As such they are more dynamic than regular variables. (for more details see Special variables)

Vectors

modifica

A vector is a sequence of zero or more OpenSCAD values. Vectors are a collection (or list or table) of numeric or boolean values, variables, vectors, strings or any combination thereof. They can also be expressions which evaluate to one of these. Vectors handle the role of arrays found in many imperative languages. The information here also applies to lists and tables which use vectors for their data.

A vector has square brackets, [] enclosing zero or more items (elements or members), separated by commas. A vector can contain vectors, which contain vectors, etc.


examples
   [1,2,3]
   [a,5,b]
   []
   [5.643]
   ["a","b","string"]
   [[1,r],[x,y,z,4,5]]
   [3, 5, [6,7], [[8,9],[10,[11,12],13], c, "string"]
   [4/3, 6*1.5, cos(60)]

use in OpenSCAD:

  cube( [width,depth,height] );           // optional spaces shown for clarity
  translate( [x,y,z] )
  polygon( [ [x0,y0],  [x1,y1],  [x2,y2] ] );
creation

Vectors are created by writing the list of elements, separated by commas, and enclosed in square brackets. Variables are replaced by their values.

  cube([10,15,20]);
  a1 = [1,2,3];
  a2 = [4,5];
  a3 = [6,7,8,9];
  b  = [a1,a2,a3];    // [ [1,2,3], [4,5], [6,7,8,9] ]  note increased nesting depth
elements within vectors

Elements within vectors are numbered from 0 to n-1 where n is the length returned by len(). Address elements within vectors with the following notation:

e[5]           // element no 5 (sixth) at   1st nesting level
e[5][2]        // element 2 of element 5    2nd nesting level
e[5][2][0]     // element 0 of 2 of 5       3rd nesting level
e[5][2][0][1]  // element 1 of 0 of 2 of 5  4th nesting level
example elements with lengths from len()
e = [ [1], [], [3,4,5], "string", "x", [[10,11],[12,13,14],[[15,16],[17]]] ];  // length 6

address       length  element
e[0]          1       [1]
e[1]          0       []
e[5]          3       [ [10,11], [12,13,14], [[15,16],[17]] ]
e[5][1]       3       [ 12, 13, 14 ]
e[5][2]       2       [ [15,16], [17] ]
e[5][2][0]    2       [ 15, 16 ]
e[5][2][0][1] undef   16
    
e[3]          6       "string"
e[3 ][2]      1       "r"
  
s = [2,0,5]; a = 2;
s[a]          undef   5
e[s[a]]       3       [ [10,11], [12,13,14], [[15,16],[17]] ]
vector operators
modifica

Template:Requires

concat() combines the elements of 2 or more vectors into a single vector. No change in nesting level is made.

 vector1 = [1,2,3]; vector2 = [4]; vector3 = [5,6];
 new_vector = concat(vector1, vector2, vector3); // [1,2,3,4,5,6]
  
 string_vector = concat("abc","def");                 // ["abc", "def"]
 one_string = str(string_vector[0],string_vector[1]); // "abcdef"

len() is a function which returns the length of vectors or strings. Indices of elements are from [0] to [length-1].

vector
Returns the number of elements at this level.
Single values, which are not vectors, return undef.
string
Returns the number of characters in string.
 a = [1,2,3]; echo(len(a));   //  3

See example elements with lengths

A matrix is a vector of vectors.

Example which defines a 2D rotation matrix
mr = [
     [cos(angle), -sin(angle)],
     [sin(angle),  cos(angle)]
    ];

Getting input

modifica

Now we have variables, it would be nice to be able to get input into them instead of setting the values from code. There are a few functions to read data from DXF files, or you can set a variable with the -D switch on the command line.

Getting a point from a drawing

Getting a point is useful for reading an origin point in a 2D view in a technical drawing. The function dxf_cross will read the intersection of two lines on a layer you specify and return the intersection point. This means that the point must be given with two lines in the DXF file, and not a point entity.

OriginPoint = dxf_cross(file="drawing.dxf", layer="SCAD.Origin", 
                        origin=[0, 0], scale=1);

Getting a dimension value

You can read dimensions from a technical drawing. This can be useful to read a rotation angle, an extrusion height, or spacing between parts. In the drawing, create a dimension that does not show the dimension value, but an identifier. To read the value, you specify this identifier from your program:

TotalWidth = dxf_dim(file="drawing.dxf", name="TotalWidth",
                        layer="SCAD.Origin", origin=[0, 0], scale=1);

For a nice example of both functions, see Example009 and the image on the homepage of OpenSCAD.

en:OpenSCAD_User_Manual/Primitive_Solids

Ritorna alla pagina utente di "Tek3327/Sandbox".