Strict Standards: Only variables should be passed by reference in /homepages/33/d411990001/htdocs/spip/config/ecran_securite.php on line 283
Modèle 3D dans Scilab - Ian’s Web Page

Modèle 3D dans Scilab

dimanche 9 janvier 2011
par  Yann
popularité : 6%

Ces travaux ont fait l’objet de 2 publications dans la revue Linux Pratique :

 Afficher des patchs dans Scilab

A partir de l’export 3DS d’un modème 3D blender, il est possible de réaliser un modèle 3D pour Scilab : un patch.

Modèle Blender

Le programme 3ds2mat suivant, basé sur la lib3ds. Il est prévu pour être compilé en « static » afin d’éviter les pbs de dépendances.

Après avoir téléchargée, désarchivée et compilée (sans l’installer) la « lib3ds », l’archive suivante doit être décompressée dans le répertoire « examples » de l’arborescence de la librairie « lib3ds ».

Archive du programme
GZ - 1.8 Mo
Programme 3ds2mat

Lancez ensuite la compilation du programme 3ds2mat par « ./configure && make ».

 Conversion d’un fichier 3DS en patch pour Scilab

Utilisez l’archive des modèles 3D suivante :

Archive des modèles
GZ - 811.6 ko
Modeles 3D et patchs

Le programme s’utilise comme suit :

./3ds2mat -t bsg_lowpoly.3ds > bsg_lowpoly.sce

l’affichage dans Scilab est réaliser à l’aide du code suivant :

//loads the 3D patch (a lowpoly one)
// from http://e2-productions.com/repository/modules/PDdownloads/viewcat.php?cid=17
exec('bsg_lowpoly.sce'); //exec('snowspeeder_scilab.sce');
//the face numbering starts à 1 (not 0 given by lib3ds)
facelist1 = facelist1 + 1;
// The face list indicates which points are composing the patch.        
//some scaling to adjust the size of the patch to the model
scale_factor = 0.6;
vertices1 = vertices1 * scale_factor;
         
// The formula used to translate the vertex / face representation into x, y, z lists
xvf = matrix(vertices1(facelist1,1),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
yvf = matrix(vertices1(facelist1,2),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
zvf = matrix(vertices1(facelist1,3),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
//plot the patch in 3D
plot3d(xvf,yvf,zvf,flag=[1,4,4]);
set(gca(),"grid",[1 1]);

On obtient :

PNG - 23.7 ko

 Mise en situation des patchs 3D sur une trajectoire

//3D trajectory
t=0:0.01:10;
x=10*sin(t);
y=3*t;
z=0.2*t.^2;
//loads the 3D patch (a lowpoly one)
// from http://e2-productions.com/repository/modules/PDdownloads/viewcat.php?cid=17
exec('bsg_lowpoly.sce');
//exec('snowspeeder_scilab.sce');
//the face numbering starts à 1 (not 0 given by lib3ds)
facelist1 = facelist1 + 1;
// The face list indicates which points are composing the patch.        
//some scaling to adjust the size of the patch to the model
scale_factor = 0.3;
vertices1 = vertices1 * scale_factor;
         
// The formula used to translate the vertex / face representation into x, y, z lists
xvf = matrix(vertices1(facelist1,1),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
yvf = matrix(vertices1(facelist1,2),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
zvf = matrix(vertices1(facelist1,3),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
//orienting the patch on the curve (tangent)
dx = diff(x);
dy = diff(y);
dz = diff(z);
// from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques
// and from http://jeux.developpez.com/faq/math/?page=transformations#Q31
// the next line computes theta_v according to y > 0 or < 0
//((bool2s(dy > 0)*2) -1) .*  acos(dx./(sqrt(dx.^2+dy.^2))) + bool2s(dy < 0)*2*%pi;
rho_v = sqrt(dx.^2+dy.^2+dz.^2); //distance computing
phi_v = acos(dz./rho_v);         //X Axis Rotation pitch
theta_v = ((bool2s(dy > 0)*2) -1).*acos(dx./(sqrt(dx.^2+dy.^2))) + bool2s(dy < 0)*2*%pi;
theta_v = - theta_v + %pi/2; //A rotation axis yaw
psi_v = [0];
psi_v = [ psi_v diff(theta_v)] *30; // roll
curFig = scf(100001);
clf(curFig,"reset");
curFig.axes_size  = [ 1600 1200 ];
curFig.figure_position = [100,100]
//some adjustments due to blender and scilab
theta =theta_v(1);  //tangage autour de l'axe vertical Y = yaw
phi = phi_v(1); //piqué rotation autour de X aile de l avion = pitch
psi = psi_v(1); //roulis autour de l'axe nez-queue = roll
//Definition of rotation matrix terms
A = cos(phi);
B = sin(phi);
C = cos(psi);
D = sin(psi);
E = cos(theta);
F = sin(theta);
//rotation matrix
M = [ C*E -C*F -D;
      -B*D*E+A*F -B*D*F+A*E -B*C;
      A*D*E+B*F -A*D*F+B*E A*C];
vertex_new=vertices1*M;
xvf = matrix(vertex_new(facelist1,1),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))';
yvf = matrix(vertex_new(facelist1,2),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))';
zvf = matrix(vertex_new(facelist1,3),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))';
//moving the patch on the curve
xvf = xvf + x(1);
yvf = yvf + y(1);
zvf = zvf + z(1);
alpha_view = 310;  //initial angle
theta_view = 70;  //initial angle
curAxe=gca();
curAxe.data_bounds=[-11 -6 -6; 11  32  22];
set(curAxe,"grid",[1 1 1]);    
//plot the 3D trajectory
param3d(x,y,z,flag=[0,4]);
//plot the patch
plot3d(xvf,yvf,zvf,alpha_view,theta_view,flag=[1,0,4]);
//getting the handle on the 3D curve
line=curAxe.children(2); //second plot = curve
line.line_style=3; //define the line style
line.thickness=2; //define the thickness of the line
line.foreground=16; //define the color of the line
//line.polyline_style=3;
//getting the handle on the 3D patch
patch=curAxe.children(1); //first plot = patch
//line.line_style=3; //define the line style
patch.thickness=0.5; //define the thickness of the lines
patch.foreground=1; ////define the color of the lines
patch.color_mode=1; //define the color of the patch
patch.hiddencolor=7; //define the color of the patch
for  i = 1:size(t,2)
  if (modulo(i,100)==0) //allow to plot 1 every 100
   
  //some adjustments due to blender and scilab
  theta = theta_v(i);
  phi = phi_v(i);
  psi = psi_v(i); //no roll, but we can simulate it
  //Definition of rotation matrix terms
  A = cos(phi);
  B = sin(phi);
  C = cos(psi);
  D = sin(psi);
  E = cos(theta);
  F = sin(theta);
  M = [ C*E -C*F -D;
        -B*D*E+A*F -B*D*F+A*E -B*C;
        A*D*E+B*F -A*D*F+B*E A*C];
  vertex_new=vertices1*M;
  xvf = matrix(vertex_new(facelist1,1),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))';
  yvf = matrix(vertex_new(facelist1,2),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))';
  zvf = matrix(vertex_new(facelist1,3),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))';
  //moving the patch on the curve
  xvf = xvf + x(i);
  yvf = yvf + y(i);
  zvf = zvf + z(i);
   
  plot3d(xvf,yvf,zvf,alpha_view,theta_view,flag=[1,0,4]);
  //getting the handle on the 3D patch
  patch=curAxe.children(1); //last plot = first children = patch
  //line.line_style=3; //define the line style
  patch.thickness=0.5; //define the thickness of the lines
  patch.foreground=1; ////define the color of the lines
  patch.color_mode=1; //define the color of the patch
  patch.hiddencolor=7; //define the color of the patch
  end;
end;
title("Trajectoire et Attitude du vaisseau","fontsize",3);

donne : PNG - 41.1 ko

 Animation simple dans Scilab

realtimeinit(0.01);//sets time unit to half a second
realtime(0);//sets current date to 0
xinit(); //create a figure
a=get("current_axes");//get the handle of the newly created axes
a.data_bounds=[-%pi,-1.1;%pi,1.1]; //fix the bounds
a.grid=[1 1]; //create the 2D grid
x = -%pi:2*%pi/100:%pi; //create the data
y=sin(x); //create the data
y2=sin(4*x); //create the data
drawlater(); //we delay the plotting
// first plot to create all objects for future access
plot(x(1),y(1),'b',x(1),y2(1),'r'); //plot only needed data
curAxe=gca(); //get the current axe handle
sin1=curAxe.children(1).children(1); //get the handle on 1st sinus
sin2=curAxe.children(1).children(2); ////get the handle on 2nd sinus
for k=2:101
    sin1.data = [x(1:k)',y(1:k)']; //we only replace the data
    sin2.data = [x(1:k)',y2(1:k)']; ////we only replace the data
    realtime(k); //every wait time
    drawnow(); //plotting
end

Apparition de sinus

Apparition de sinus

realtimeinit(0.1);//sets time unit to half a second
realtime(0);//sets current date to 0
x= [0 0 1 1];
y = [0 1 1 0];
xinit(); //create a figure
curAxes = gca();
//curAxes.data_bounds=[-1,-1;2,2]; //fix the bounds
square(-1,-1,2,2);
curAxes.grid=[1 1]; //create the 2D grid
xset("color",2)
xfpoly(x,y);
drawlater();
xy = [x;y];
t = 0:2*%pi/100:2*%pi;
//rotation
for  i=1:length(t),
    drawlater();
    xy1=rotate(xy,t(i),[0.5;0.5]);
    curAxes.children(1).data = xy1';
    realtime(i); //every wait time
    drawnow();
end
drawlater();
//déplacement
realtimeinit(0.01);
realtime(0);
t = 0:2*%pi/100:2*%pi
//x_pos = sin(t);
x_pos = linspace(0,1, length(t));
y_pos = linspace(0,1, length(t));
//y_pos = cos(t);
for  i=1:length(t),
    drawlater();
    x_new = x +x_pos(i);
    y_new = y +y_pos(i);
    xy1 = [x_new;y_new];
    curAxes.children(1).data = xy1';
    realtime(i); //every wait time
    drawnow();
end
//les deux
drawlater();
//déplacement
realtimeinit(0.1);
realtime(0);
t = 0:2*%pi/100:2*%pi
x_pos = cos(t);
//x_pos = linspace(0,1, length(t));
//y_pos = linspace(0,1, length(t));
y_pos = sin(t);
for  i=1:length(t),
    drawlater();
    xy1=rotate(xy,4*t(i),[0.5;0.5]);
    x_new = xy1(1,:)+x_pos(i);
    y_new = xy1(2,:)+y_pos(i);
    curAxes.children(1).data = [x_new;y_new]';
    realtime(i); //every wait time
    drawnow();
end

rotation, translation et les deux

rotation, translation et les deux

 Animation de notre vaisseau avec scilab et création d’un GIF animé

clear all;
usecanvas(%F);
//usecanvas(%F); si la carte graphique supporte et en met pas le warning
//ATTENTION : A cause des limitations de votre configuration, Scilab est passé dans un mode dans lequel mélanger des uicontrols et des graphique n'est pas possible. Tapez "help usecanvas" pour plus d'information
//Scilab uses a "GLJPanel" %F (a Swing OpenGL component) to display graphics (plot3d, plot, ...). This component uses some high level OpenGL primitives which are not correctly supported on some platforms (depending on the operating system, video cards, drivers ...)
//Linux
//NVIDIA Card With free drivers.
//ATI Card With free drivers or ATI-drivers with version < 8.52.3 (Installer version < 8.8 / OpenGL version < 2.1.7873).
// INTEL Card With Direct Rendering activated.
//Simulated 3D trajectory
t=0:0.1:10;
x=10*sin(t);
y=3*t;
z=0.2*t.^2;
//loads the 3D patch (a lowpoly one)
// from http://e2-productions.com/repository/modules/PDdownloads/viewcat.php?cid=17
exec('bsg_lowpoly.sce');
//exec('snowspeeder_scilab.sce');
//the face numbering starts à 1 (not 0 given by lib3ds)
facelist1 = facelist1 + 1;
// The face list indicates which points are composing the patch.        
//some scaling to adjust the size of the patch to the model
scale_factor = 0.4;
vertices1 = vertices1 * scale_factor;
// The formula used to translate the vertex / face representation into x, y, z lists
xvf = matrix(vertices1(facelist1,1),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
yvf = matrix(vertices1(facelist1,2),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
zvf = matrix(vertices1(facelist1,3),size(facelist1,1),length(vertices1(facelist1,1))/size(facelist1,1))';
         
//orienting the patch on the curve (tangent)
dx = diff(x);
dy = diff(y);
dz = diff(z);
// from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques
// and from http://jeux.developpez.com/faq/math/?page=transformations#Q31
// the next line computes theta_v according to y > 0 or < 0
//((bool2s(dy > 0)*2) -1) .*  acos(dx./(sqrt(dx.^2+dy.^2))) + bool2s(dy < 0)*2*%pi;
rho_v = sqrt(dx.^2+dy.^2+dz.^2); //distance computing
phi_v = acos(dz./rho_v);         //X Axis Rotation : Pitch is acting about an axis perpendicular to the longitudinal plane of symmetry
theta_v = ((bool2s(dy > 0)*2) -1).*acos(dx./(sqrt(dx.^2+dy.^2))) + bool2s(dy < 0)*2*%pi;
theta_v = - theta_v + %pi/2; //A rotation axis yaw : The yaw is about the vertical body axis,
psi_v = [0];
psi_v = [ psi_v diff(theta_v)] *2; // roll is acting about the longitudinal axis
curFig = scf(100001);
clf(curFig,"reset");
curFig.axes_size  = [ 1600 1200 ];
curFig.figure_position = [100,100]
//Set the evolution of the view angles Theta and Alpha
//---------------------------------------------------
alpha_view = 260;  //initial angle
alpha_end_view = 245;//215; // final angle
theta_view =75;  //initial angle
theta_end_view = 75; // final angle
A=linspace(alpha_view,alpha_end_view, size(t,2)-1);
T=linspace(theta_view,theta_end_view, size(t,2)-1);
Angles=[T;A]; //Angle Matrix
drawlater(); // delay the plotting until drawnow() is called
show_window(curFig); //raise the graphic window
//plot the 3D trajectory
param3d(x,y,z,flag=[0,4]);
curAxe=gca();
//plot the patch in "initial" position
plot3d(xvf,yvf,zvf,alpha_view,theta_view,flag=[1,0,4]);
set(gca(),"grid",[1 1 1]); //put the grid on the figure
// set 3D boundaries
curAxe.data_bounds=[-11 -6 -6; 11  32  22];
title("Animation et rotation d''un patch 3d.","fontsize",3);
s=gce(); //the handle on the surface
//curFig.background = -1;                 // black
//curAxe.background    = -1;                 // gray
//curAxe.foreground    = 14;                 // white
//getting the handle on the 3D curve
line=curAxe.children(2); //second plot = curve
line.line_style=3; //define the line style
line.thickness=2; //define the thickness of the line
line.foreground=16; //define the color of the line
//line.polyline_style=3;
//getting the handle on the 3D patch
patch=curAxe.children(1); //first plot = patch
//line.line_style=3; //define the line style
patch.thickness=0.5; //define the thickness of the lines
patch.foreground=1; ////define the color of the lines
patch.color_mode=1; //define the color of the patch
patch.hiddencolor=7; //define the color of the patch
winnum=winsid();//getting the window number
//drawnow();
frame_duration = 0.05
realtimeinit(frame_duration); //fix (if possible, regarding to calculus) the duration of one frame
realtime(0);
   
for  i = 1:size(t,2)-1 //due to the the "diff" computing
  drawlater();
  //setting the angles
  theta = theta_v(i); //Yaw
  phi = phi_v(i);  //Pitch
  psi = psi_v(i); //Roll
  //Definition of rotation matrix terms
  A = cos(phi);
  B = sin(phi);
  C = cos(psi);
  D = sin(psi);
  E = cos(theta);
  F = sin(theta);
  //Definition of the rotationmatrix
  M = [ C*E -C*F -D;
        -B*D*E+A*F -B*D*F+A*E -B*C;
        A*D*E+B*F -A*D*F+B*E A*C];
  //new verteces locations
  vertex_new=vertices1*M;
  //modification of the patch on the figure
  s.data.x = matrix(vertex_new(facelist1,1),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))' + x(i);
  s.data.y = matrix(vertex_new(facelist1,2),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))' + y(i);
  s.data.z = matrix(vertex_new(facelist1,3),size(facelist1,1),length(vertex_new(facelist1,1))/size(facelist1,1))' + z(i);
  //if rotation animation
  curAxe.rotation_angles = Angles(:,i); //change the view angles property
  realtime(i); //wait till date frame_duration*i seconds
  drawnow(); //plotting all the stuff on the figure
  //recording each frame in a gif file (see doc for other format)
    if pmodulo(i,1)==0 then //use pmodulo to save a frame each n frame
    nom_image='capture/image_'+string(1000+i)+'.gif';
    xs2gif(winnum,nom_image);//on sauve dans le répertoire courant
    //create animated gif with imagemagic fabulous convert program :-)
    //convert -delay 10 -loop 0 image2_*.gif animation2.gif
    nom_image='capture/image_'+string(1000+i)+'.png';
    xs2png(winnum,nom_image);//on sauve dans le répertoire courant
    //create animated png  with apngasm program :-)
    //./apngasm output.png image_1*.png 1 10 /l0
  end
end

ce qui donne en Gif

GIF - 1.1 Mo

et en Png

PNG - 1.1 Mo


Navigation

Articles de la rubrique

Météo

Metz, 57, France

Conditions météo à 16h00
par weather.com®

Soleil voilé

32°C


Soleil voilé
  • Vent : 11 km/h - sud
  • Pression : 985 mbar tendance symbole
Prévisions >>

Prévisions du 28 mai
par weather.com®

Soleil voilé

Max 33°C
Min 17°C


Soleil voilé
  • Vent : 11 km/h
  • Risque de precip. : %
<< Conditions  |  Prévisions >>

Prévisions du 29 mai
par weather.com®

Soleil

Max 35°C
Min 16°C


Soleil
  • Vent : 16 km/h
  • Risque de precip. : 0%
<<  Prévisions  >>

Prévisions du 30 mai
par weather.com®

Averses

Max 26°C
Min 14°C


Averses
  • Vent : 17 km/h
  • Risque de precip. : 70%
<<  Prévisions  >>

Prévisions du 31 mai
par weather.com®

Soleil et nuages épars

Max 26°C
Min 12°C


Soleil et nuages épars
  • Vent : 9 km/h
  • Risque de precip. : 20%
<<  Prévisions  >>

Prévisions du 1er juin
par weather.com®

Soleil et nuages épars

Max 28°C
Min 12°C


Soleil et nuages épars
  • Vent : 12 km/h
  • Risque de precip. : 0%
<<  Prévisions  >>

Prévisions du 2 juin
par weather.com®

Soleil

Max 28°C
Min 14°C


Soleil
  • Vent : 9 km/h
  • Risque de precip. : 0%
<<  Prévisions  >>

Prévisions du 3 juin
par weather.com®

Orage épars

Max 27°C
Min 13°C


Orage épars
  • Vent : 14 km/h
  • Risque de precip. : 40%
<< Prévisions


Brèves

25 février 2011 - Scilab : Application GUI

Application GUI dans Scilab : Étude des systèmes automatiques. Systèmes Linéaires

9 janvier 2011 - Modèle 3D dans Scilab

Afficher des patchs dans Scilab à partir de Modèle 3D blender. Modèle 3D dans (...)

2 octobre 2010 - Plugins LDraw pour Blender 2.49

Importez vos modèles LEGO (MLCad et autres) dans blender grâce au plugin d’importation (...)