File : lattice-io-vrml.adb
with Ada.Text_IO, Ada.Strings.Fixed;
use Ada.Text_IO;
package body Lattice.IO.VRML is
type D is delta 0.001 range -999.0 .. 999.0;
package D_IO is new Ada.Text_IO.Fixed_IO(D);
use D_IO;
procedure PutHeader(F: in File_Type) is
begin
Put_Line(F,"#VRML V2.0 utf8");
New_Line(F);
end PutHeader;
procedure PutBall(F: in File_Type; L: in IPoint; R: in Rep) is
P: constant RPoint := Coord(L);
begin
Put_Line(F,"Transform {");
Put(F," translation ");
Put(F,D(P(1))); Put(F," ");
Put(F,D(P(2))); Put(F," ");
Put(F,D(P(3))); Put(F," ");
New_Line(F);
Put_Line(F," children [");
Put_Line(F," Shape {");
Put(F," geometry Sphere { radius ");
Put(F,D(R));
Put_Line(F," }");
Put_Line(F," appearance Appearance {");
Put_Line(F," material Material {diffuseColor 0.8 0.7 0.4}");
Put_Line(F," }");
Put_Line(F," }");
Put_Line(F," ]");
Put_Line(F,"}");
New_Line(F);
end PutBall;
procedure PutPoints(F: in File_Type; L: in IPointVec) is
P: RPoint;
begin
Put_Line(F,"Shape {");
Put_Line(F," appearance Appearance {");
Put_Line(F," material Material {");
Put_Line(F," emissiveColor 1.0 1.0 1.0");
Put_Line(F," }");
Put_Line(F," }");
Put_Line(F," geometry PointSet {");
Put_Line(F," coord Coordinate {");
Put_Line(F," point [");
for I in L'Range loop
P := Coord(L(I));
Put(F," ");
Put(F,D(P(1))); Put(F," ");
Put(F,D(P(2))); Put(F," ");
Put(F,D(P(3))); Put(F,",");
New_Line(F);
end loop;
Put_Line(F," ]");
Put_Line(F," }");
Put_Line(F," }");
Put_Line(F,"}");
New_Line(F);
end PutPoints;
procedure PutLine(F: in File_Type; L1,L2: in IPoint) is
P1: constant RPoint := Coord(L1);
P2: constant RPoint := Coord(L2);
begin
Put_Line(F,"Shape {");
Put_Line(F," appearance Appearance {");
Put_Line(F," material Material {");
Put_Line(F," emissiveColor 1.0 1.0 1.0");
Put_Line(F," }");
Put_Line(F," }");
Put_Line(F," geometry IndexedLineSet {");
Put_Line(F," coord Coordinate {");
Put_Line(F," point [");
Put(F," ");
Put(F,D(P1(1))); Put(F," ");
Put(F,D(P1(2))); Put(F," ");
Put(F,D(P1(3))); Put(F,",");
New_Line(F);
Put(F," ");
Put(F,D(P2(1))); Put(F," ");
Put(F,D(P2(2))); Put(F," ");
Put(F,D(P2(3))); Put(F,",");
New_Line(F);
Put_Line(F," ]");
Put_Line(F," }");
Put_Line(F," coordIndex [");
Put_Line(F," 0, 1");
Put_Line(F," ]");
Put_Line(F," }");
Put_Line(F,"}");
New_Line(F);
end PutLine;
function Box(B: Poly) return IPointVecPtr is
L1,L2,L3: Integer := 99;
R1,R2,R3: Integer := -99;
N: Integer := 0;
P: IPoint;
begin
for K in 1 .. B.L loop
P := UnPack(B.V(K));
L1 := Integer'Min(L1,P(1));
R1 := Integer'Max(R1,P(1));
L2 := Integer'Min(L2,P(2));
R2 := Integer'Max(R2,P(2));
L3 := Integer'Min(L3,P(3));
R3 := Integer'Max(R3,P(3));
end loop;
for I1 in L1 .. R1 loop
for I2 in L2 .. R2 loop
for I3 in L3 .. R3 loop
if FitsType((I1,I2,I3)) then
N := N+1;
end if;
end loop;
end loop;
end loop;
declare
L: IPointVecPtr := new IPointVec(1 .. N);
begin
N := 0;
for I1 in L1 .. R1 loop
for I2 in L2 .. R2 loop
for I3 in L3 .. R3 loop
if FitsType((I1,I2,I3)) then
N := N+1;
L(N) := Pt(I1,I2,I3);
end if;
end loop;
end loop;
end loop;
return L;
end;
end Box;
procedure WriteVRML(Name: in String; B: in PolyPtr) is
N: Integer := 1;
OnePlus: constant Rep := 1.001;
RL: constant Rep := 0.3;
RS: constant Rep := 0.1;
P1,P2: IPoint;
L: IPointVecPtr := Box(B.all);
F: File_Type;
begin
Put_Line("writing " & Name);
Create(F,Out_File,Name);
PutHeader(F);
PutPoints(F,L.all);
Free(L);
while B.V(N) >= Fac3 loop
P1 := UnPack(B.V(N));
PutBall(F,P1,RL);
for K in 1 .. N-1 loop
P2 := UnPack(B.V(K));
if RDist(P1,P2)<OnePlus then
PutLine(F,P1,P2);
end if;
end loop;
N := N+1;
exit when N>B.L;
end loop;
while N <= B.L loop
P1 := UnPack(B.V(N));
PutBall(F,P1,RS);
N := N+1;
end loop;
Close(F);
end WriteVRML;
end Lattice.IO.VRML;