|
Se pueden declarar identificadores para referenciarlos más tarde y hacer así las escenas más legibles, pero también para poder parametrizar la escena de manera que, cambiando una simple declaración, se cambien diferentes valores. Existen varios identificadores incorporados que POV-Ray declara por ti. Mira las secciones "Identificadores predefinidos de coma flotante" e "Identificadores vectoriales predefinidos" para más detalles.
Un identificador se declara de la siguiente forma:
DECLARACION: #declare IDENTIFICADOR = DVALOR | #localIDENTIFICADOR = DVALOR DVALOR: COMA FLOTANTE; | VECTOR; | COLOR; | CADENA | OBJETO | TEXTURA | PIGMENTO | NORMAL | ACABADO | INTERIOR | MEDIA | DENSIDAD | MAPA_DE_COLOR | MAPA_DE_PIGMENTO | MAPA_DE_INCLINACION | MAPA_DE_NORMAL | MAPA_DE_DENSIDAD | CAMARA | FUENTE_DE_LUZ | NIEBLA | ARCOIRIS | ESFERA_CELESTE | TRANSFORMACION
Donde IDENTIFICADOR es el nombre de un identificador de hasta 40 caracteres de longitud, y DVALOR es cualquiera de los ítems citados. Se les llama así porque son valores que pueden aparecer a la derecha del signo igual. La sintaxis para cada uno se encuentra en la correspondiente sección de esta referencia del lenguaje.
#declare Filas = 5; #declare Contador = Contador+1; #local Aqui = <1,2,3>; #declare Blanco = rgb <1,1,1>; #declare Cyan = color blue 1.0 green 1.0; #declare Fuente = "ariel.ttf" #declare Rodillo = cylinder {-5*x,5*x,1} #declare Anillo = torus {5,1} #local Cuadros = pigment { checker White, Cyan } #declare Reduccion = 0.5; object{ Rodillo scale y*5 } // no "cylinder { Rodillo }" object { Anillo pigment { Cuadros scale 0.5 } transform Reduccion }
Nota: Observa que debe haber un punto y coma después de la expresión siempre que se trate de valores de coma flotante, vectores o colores. Este punto y coma fue introducido en la versión 3.1 de POV-Ray. Si se omite, POV-Ray genera un mensaje de alerta y además, algunas macros pueden no funcionar correctamente.
Las declaraciones, como la mayoría de directivas del lenguaje, pueden aparecer en cualquier parte del archivo, incluso dentro de otras sentencias. Por ejemplo:
#declare Aqui=<1,2,3>; #declare Contador=0; // inicializa el contador union { object { Rodillo translate Aqui*Contador } #declare Contador=Contador+1; // lo redeclara dentro de la unión object { Rodillo translate Aqui*Contador } #declare Contador=Contador+1; // lo redeclara dentro de la unión object { Rodillo translate Aqui*Contador } }
Como muestra este ejemplo, puedes redeclarar un identificador y usar su contenido previo en la propia redeclaración.
Nota: Los identificadores de objetos
usan la sentencia de envoltorio genérico object{
... }
.
No necesitas saber qué tipo de objeto es cuando lo citas.
Las declaraciones se pueden anidar hasta cierto punto. En el ejemplo de la sección anterior podrías declarar la unión entera como un objeto. Sin embargo, por razones técnicas, hay ciertas situaciones en las que no puedes usar una directiva del lenguaje dentro de la declaración de expresiones de coma flotante, vectores o colores. Aunque estos límites se han reducido desde POV-Ray 3.1, todavía existen.
Los identificadores declarados dentro del bloque #macro
... #end
no se crean cuando se
define la macro, sino cuando se invoca. Al igual que otros ítems dentro
de una definición #macro, se ignoran en la definición de la macro.
Los identificadores se pueden declarar tanto globales, usando la
directiva #declare
, como
locales, usando la directiva #local
.
Los identificadores creados mediante la directiva #declare
son de duración permanente y alcance global. Una vez creados, están
disponibles para toda la escena, y no pueden ser liberados hasta el
final del análisis o hasta que se destruyan específicamente usando #undef
.
Véase "Destruyendo Identificadores" para más detalles.
Aquellos creados con la directiva #local
son de
duración temporal y de alcance local. Sobreescriben temporalmente
cualquier identificador con el mismo nombre. Véase "Conflictos en nombre de identificadores".
Si la directiva #local
se usa dentro de una sentencia #macro
,
el identificador será local para esa macro. El identificador se crea
cuando se invoca la macro y se analiza la directiva #local
.
Persiste hasta que se alcanza la directiva #end
de final
de la macro, momento en el que se destruye. Las siguientes invocaciones
de la macro crean identificadores totalmente nuevos.
El uso de #local
dentro de un archivo de inclusión,
pero no en una macro, también crea un identificador temporal local al
archivo de inclusión. Cuando el archivo se incluye y se analiza la
directiva #local
, se crea el identificador, que permanece
hasta que se alcanza el final del archivo de inclusión y se destruye.
Las siguientes inclusiones del archivo dan lugar a identificadores
totalmente nuevos.
Si se usa la directiva #local
en el archivo
principal de escena (no en un fichero de inclusión ni en una macro), se
comporta igual que la directiva #declare
. Por
claridad, no deberías usar #local
en el archivo
principal, excepto dentro de macros.
No hay actualmente una manera de crear identificadores locales permanentes en POV-Ray.
Los identificadores locales pueden liberarse específicamente usando #undef
, pero en general, no existe la
necesidad de hacerlo. Mira la sección "Destruyendo
Identificadores" para más detalles.
Los identificadores locales pueden usar nombres de identificadores ya declarados. La precedencia corresponde al identificador más reciente y más local. Cuando se incluye un archivo o se invoca una macro, se crea una nueva tabla de símbolos. Cuando referenciamos identificadores, se buscan primero en la tabla de símbolos más reciente, después en la siguiente más reciente y así sucesivamente hasta llegar a la tabla global del archivo de escena principal. Cada vez que se sale de una macro o archivo de inclusión, se destruyen su tabla y sus identificadores. Los parámetros pasados por valor residen en la misma tabla de símbolos usada para los identificadores locales de la macro.
Las reglas para duplicar nombres de identificador pueden parecer complicadas cuando se usan múltiples macros o archivos de inclusión anidados, pero, en la práctica real, suelen dar los resultados esperados.
Considera el siguiente ejemplo: tienes un archivo principal de
escena llamado myscene.pov
que contiene:
#declare A = 123; #declare B = rgb<1,2,3>; #declare C = 0; #include "myinc.inc"
Dentro del archivo de inclusión, invocas a una macro llamada MiMacro(J,K,L)
.
Observa que no es importante dónde esté definida MiMacro
,
siempre que sea antes de ser invocada. En este ejemplo, lo importante
es que la macro se invoca desde dentro de mi_inc.inc
.
Los identificadores A
, B
, y C
están generalmente disponibles en todos los niveles. Si mi_inc.inc
o MiMacro
contienen, por ejemplo, la sentencia #declare
C=C+1;
, entonces el valor de C
cambia en cualquier
parte, tal y como esperabas.
Ahora supón que dentro de mi_inc.inc
haces lo
siguiente...
#local A = 546;
La versión global de A
se oculta y se crea una nueva A
que está también disponible dentro de MiMacro
, ya que ésta
se invoca desde mi_inc.inc
. Una vez que sales de mi_inc.inc
,
la variable local A
se destruye y se restaura la variable
original A
con su valor de 123
. Como habías
creado la variable local A
dentro de mi_inc.inc
,
no hay ninguna manera de referenciar la variable global original A
hasta que uses #undef A
, o finalice el archivo de
inclusión. La directiva #undef
siempre destruye la versión más local de un identificador.
De manera similar, si MiMacro
contuviera...
#local B = box{0,1}
se crearía un nuevo identificador B
local a la macro.
El valor original de B
permanece oculto y se restaura
cuando finaliza la macro. Observa que la local B
no tiene por qué ser del mismo tipo que la original.
La cosa se complica cuando intentamos asignar un nuevo valor a un
identificador que fue declarado local en un nivel anterior. Supón que
dentro de mi_inc.inc
haces lo siguiente...
#local D = 789;
Si desde dentro de mi_inc.inc
quieres incrementar D
en uno, deberías hacer lo siguiente:
#local D = D + 1;
pero si intentas hacer esto dentro de MiMacro
crearás
una nueva variable D
que será local a MiMacro
y no incrementarás la variable D
original, que es externa a MiMacro
pero local a mi_inc.inc
. Lo que has ordenado es "crear una
nueva variable D
local a MiMacro
cogiendo el
valor de la variable D
local a mi_inc.inc
más
uno". Seguramente, no es lo que querías. En vez de ello, deberías de
hacer lo siguiente:
#declare D = D + 1;
Puedes pensar que esto crearía una nueva D
global, pero
realmente incrementa el valor de la variable D
declarada
en mi_inc.inc
. ¿Confundido? Aquí están las reglas:
#declare
como en #local
. #local
,
el identificador que se está creando o al que se está asignando un
nuevo valor, SIEMPRE se crea en el nivel actual de anidamiento de la
macro o del archivo de inclusión. #declare
, se crea con alcance global y se almacena
en la tabla de símbolos del archivo de escena principal. #declare
,
éste se asigna a la versión más local y reciente en ese momento. En resumen, #local
siempre significa "el nivel actual",
mientras que #declare
significa "global" para
identificadores nuevos y "el más reciente" para identificadores
existentes.
Los identificadores creados con #declare
persisten,
generalmente, hasta que el análisis de la escena ha finalizado. Los
identificadores creados con #local
duran sólo hasta el fin
de la macro o el archivo de inclusión en que se crearon. Sin embargo,
puedes destruir un identificador usando la directiva #undef
.
Por ejemplo:
#undef MiValor
Si existieran múltiples versiones locales anidadas del identificador, sólo la más reciente y más local será destruida, existiendo todavía los identificadores con idéntico nombre que fueron creados en niveles superiores.
Véase también "las Directivas #ifdef e #ifndef".
|