Loop no retiene los cambios

Cesar Saez - 09/01/2009 21:58
Hola, esta pregunta no se ni siquiera como plantearla, seguro le habrá pasado a muchos, me gustaría saber si existe alguna forma de solucionarlo más elegante que lo que vengo haciendo últimamente.

El tema va así, algunas veces me sucede que al ejecutar una acción dentro de un loop/bucle por alguna razón ejecuta la línea, pero no retiene los cambios. Es como si hiciera el cambio, pero luego lo sobrescribe sin motivo aparente volviendo al valor original. No tiene sentido ¿no?
Dejo un ejemplo.
[code]Fn createspline pospoints = -retorna una Spline usando las coordenadas del array pospoint.
(Tlocal ss = splineshape Pos pospoints[1]) taddnewspline ss tfor each in pospoints do t(t addknot ss 1 #smooth #curve each t) tupdateshape ss treturn ss).
(Tlocal myspline = createspline #([0,0,0], [50,0,0], [100,0,0]) -creo una Spline tmyspline, rotation, z_rotation = 45 taddmodifier myspline (Spline IK control()) -agregamos un modificador Spline IK control tlocal splinemod = myspline. Modifiers[1] tsplinemod, linktypes = 2 -los helpers no van enlazados entre sí tsplinemod, createhelper (numknots myspline) -creamos los helpers que controlanran la curva t-atencion:
-supongamos que quiero igualar la orientación de los t-controles creados mediante el modificador con la Spline tfor each in splinemod, helper_list do t(t each, rotation = myspline, rotation -igualamos la rotación con la Spline print (each, name + : + each, rotation as string) -dejamos un log para comprobar posteriormente t).
)[/code]

El log retorna que cambió la orientación de todos los controles como es de esperar:
[code]Point01: (quat 0 0 0.382683 0.9238.

Point02: (quat 0 0 0.382683 0.9238.

Point03: (quat 0 0 0.382683 0.9238 [/code]

Pero el resultado difiere, sólo cambió la orientación del primero, de alguna forma no fue capaz de retener el cambio en el resto de los nodos del array:

🖼️

Estamos trabajando para mostrar las imágenes del foro

Adjunto #90421


De hecho, si hago la rotación con autokey en el frame 1 queda animado y en el cuadro 1 todos tienen la orientación como corresponde, es como si el loop no fuera capaz de retener los valores o los sobrescribiera de alguna forma.

Alguien sabe cuál es el problema? Que estoy haciendo mal? Gracias.

Posdata: si hiciera el loop usando un índice para recorrer el array (como en el código de abajo) el resultado es exactamente el mismo.
[code]for i=1 todo splinemod, helper_list, count do.
(Tsplinemod, helper_list.rotation = myspline, rotation -igualamos la rotación con la Spline Tprint (splinemod, helper_list.name + : + splinemod, helper_list[i].rotation as string) -dejamos un log para comprobar posteriormente.
)[/code]

-- IMÁGENES ADJUNTAS --

🖼️

Estamos trabajando para mostrar las imágenes del foro

Adjunto #90421

iherrero20 - 09/01/2009 23:03
No sé a qué te refieres, los nodos están todos rotados, cada uno está en diferente posición, si quieres que estén todos en la misma posición tendrás que igualar los otros nodos al primero.

Si recorres todos los nodos todos cambiaran, si quieres que todos estén afectados por el primero sin cambiar debes igualar la matriz al primer elemento.
Cesar Saez - 10/01/2009 00:10

No sé a qué te refieres, los nodos están todos rotados, cada uno está en diferente posición, si quieres que estén todos en la misma posición tendrás que igualar los otros nodos al primero.

Si recorres todos los nodos todos cambiaran, si quieres que todos estén afectados por el primero sin cambiar debes igualar la matriz al primer elemento.

El bucle intenta igualar la rotación de cada nodo a la Spline (cuya rotación se mantiene contante). El log indica que efectivamente se realizó la rotación a cada nodo, pero de alguna forma no se refleja en la interfaz.

Siguiendo tu sugerencia (cambiando el loop por algo como lo de abajo) sucede exactamente lo mismo.
[code]splinemod, helper_list[1].rotation = myspline, rotation.

For I=2 todo splinemod, helper_list, count do.
(Tsplinemod, helper_list.rotation = splinemod, helper_list[1].rotation -igualamos la rotación con la Spline Tprint (splinemod, helper_list.name + : + splinemod, helper_list[i].rotation as string) -dejamos un log para comprobar posteriormente.
)[/code] Gracias de todas formas.
kiko_L - 10/01/2009 00:52
Vaya César, llevo un buen rato mirando el código y no hay manera de encontrar el fallo. Me tiene muy mosca. Le seguiré dando vueltas a ver si descubro algo y si encuentras el fallo coméntanos. Un saludo.
phoelix - 10/01/2009 02:23
Hola César. Hay un detalle cuando defines la propiedad rotation de un nodo, y es que está asignación es interpretada en coordenadas de transformación globales, por lo tanto estarías rotando el objeto con respecto al origen, para rotarlo con respecto a sí mismo tendrías que hacerlo de esta forma:
[code]in cordsys each each, rotation = myspline, rotation[/code]

Pero en esto no se encuentra el problema que mencionas sobre las rotaciones sobrescritas, lo que sucede en el caso de los helpers de un Spline IK Control es que el modificador define las posiciones y las rotaciones de estos helpers en el momento en el que el visor se actualiza, al tener todo el código entre paréntesis el visor no se actualizara hasta que se ejecute todo lo que está allí dentro, por lo tanto todas las transformaciones que realices serán sobrescritas al final, extrañamente a excepción de los helpers que se encuentren en el origen (como el primero).

Si, por ejemplo, cambiaras las posiciones de los helpers dentro de ese pedazo de código (no necesariamente dentro de un loop) al final también serían sobrescritas.

Si quitaras los paréntesis te funcionaria ya que el visor se actualiza por cada línea de código ejecutada globalmente, pero obviamente esto no será posible en todos los casos.

Hay dos formas de solucionarlo, la primera seria poner un Redraw All Views() después de que creas los helpers en el splineikcontrol, y la otra seria crear los helpers manualmente, alinearlos a los vértices del Spline y luego asignarlos al splineikcontrol.
[code]Fn createspline pospoints = -retorna una Spline usando las coordenadas del array pospoint.
(Tlocal ss = splineshape Pos pospoints[1]) taddnewspline ss tfor each in pospoints do t(t addknot ss 1 #smooth #curve each t) tupdateshape ss treturn ss).
(Tlocal myspline = createspline #([0,0,0], [50,0,0], [100,0,0]) -creo una Spline tmyspline, rotation, z_rotation = 45 taddmodifier myspline (Spline IK control()) -agregamos un modificador Spline IK control tlocal splinemod = myspline. Modifiers[1] tsplinemod, linktypes = 2 -los helpers no van enlazados entre sí tsplinemod, createhelper (numknots myspline) -creamos los helpers que controlanran la curva t[font=arial black"]Redraw All Views()[/font] t-atencion:
-supongamos que quiero igualar la orientación de los t-controles creados mediante el modificador con la Spline tfor each in splinemod, helper_list do t(t [font=arial black"]in cordsys each[/font] each, rotation = myspline, rotation -igualamos la rotación con la Spline print (each, name + : + each, rotation as string) -dejamos un log para comprobar posteriormente t).
)[/code]

Método de creación manual de helpers:
[code]Fn createspline pospoints = -retorna una Spline usando las coordenadas del array pospoint.
(Tlocal ss = splineshape Pos pospoints[1]) taddnewspline ss tfor each in pospoints do t(t addknot ss 1 #smooth #curve each t) tupdateshape ss treturn ss).
(Tmyspline = createspline #([10,0,0], [50,0,0], [100,0,0]) -creo una Spline tmyspline, rotation, z_rotation = 45 taddmodifier myspline (Spline IK control()) -agregamos un modificador Spline IK control tsplinemod = myspline. Modifiers[1] t-se crean los helpers y se alinean con los vértices thelperarray=#() tfor i=1 todo (numknots myspline) do t(t append helperarray (point Pos getknotpoint myspline 1 i)) t) t-se agregan los vértices al Spline IK control tsplinemod, helper_list=helperarray t-se alinean las rotationes tfor each in splinemod, helper_list do t(t in cordsys each each, rotation=myspline, rotation t).
)[/code]
Ruramuq - 10/01/2009 04:46
Vaya, muy astuto, había intentado con Redraw All Views, pero no entendía bien por qué, así que, no respondí. Porque hará max esas cosas cuando uno podría usar with redraw of.
Cesar Saez - 10/01/2009 04:51
Vaya, gracias Phoenix, a esta altura eres mi gurú personal, siempre me terminas resolviendo la papeleta. muchas gracias, por esta y por las anteriores.
Cesar Saez - 10/01/2009 04:56
Y oRuramuqo también, que conste. Gracias a todos por ayudarme (o tener la intención, que es lo que cuenta) con mis dudas.
phoelix - 13/01/2009 22:04
Vale César, que bueno que te halla sido de utilidad.