A while ago I made some statements about a modeller I've hacked together for
X. Silly me.

I've been inundated with requests for ftp-sites where Capov! can be found,
so I think I'd better 'release' some details about Capov!, the vapourware
which would make even the Gates of Hell proud.

Let me start with the pros.

o Input/output - .POV and .pl (prolog files) The input of .POV files is not
  perfect, though, as the grammar I used contained some errors.
  Easy to add support for other formats.
o Display: The three isometric views, which can be panned and scaled
  independently. The perspective camera view will be added some time in the
  future. Not necessarily the near future, either.
  Not all objects are displayable: at the moment I think only spheres,
  boxes, cones, cylinders, light_sources, torii, union etc. and declares are
  displayed. Oh, and triangles, smooth and otherwise.
o Hierarchical listing of objects. i.e. object is a union of sphere and
  difference of...
  (But a bit better than that example might seem to imply! :-)
o Parametric declares.
     e.g.
        #declare open_cylinder(Start,End,RMajor,Rminor) = difference {
              cylinder { Start, End, RMajor }
              cylinder { Start*1.01, End*1.01, Rminor }
           }
        and then later:
        object { open_cylinder(<-1,-1,-1>,<1,1,1>,2,1) texture {....} }
o rotate, scale and translate in any order (of course!)
o complex and compound textures, which may be defined before or after
  object transformations.
o Spline curves (hermite, bezier, b-spline and catmull-rom).
o Various 'physical laws'. e.g. gravitation
o An onomatopoetic name.
  (Well, somebody had already taken PovCad, and as CadPov sounded silly,...)
  Note: The exclamation mark is obligatory.
o By far the most important feature of Capov! is the programming interface.
  Objects are typically created using a command such as 
          nso(sphere([centre(10,0,0),radius(4),texture('SphereTexture')]))
          (nso is synonymous with 'new_screen_object')
  To create a ring, radius 10, around the y axis, 5 units up, of torii, all
  of which 'point' at the origin, and with major axis 3, minor 1, try:
  ring :-
     NoTorii = 100, % 100 torii
     new_declared(ring_torus,torus([maj_rad(3),min_rad(1)])),
     forall(  between(1,NoTorii,I),
        (  Degs is I*NoTorii/360.0,
           X is 10*degs_sin(Degs),
           Y is 5,
           X is 10*degs_cos(Degs), % ok, so (X,Y,Z) is the position of the torus
           angles_of_vector(vector(X,Y,Z),Alpha,Beta), % or some similar name
           nso(ring_torus([translate(X,Y,Z),rotate(Alpha,Beta,0)])
         )
      ).
   (I haven't actually tried the above examples - profound apologies if it
   doesn't work. And ignore the fact that there are easier ways of doing the
   latter example! :-)
   A b-spline with 100 spheres of radius 1 given control-points
   ControlPoints, may be created thusly:
   spline_ex :-
      spline(b_spline,ControlPoints,100,Ps),
      forall( member(P,Ps),
         (  [X,Y,Z] = P ; vector(X,Y,Z) = P,
            nso(sphere([centre(X,Y,Z),radius(1)]))
         )
      ).
   Or, equally:
   spline(b_spline,ControlPoints,100,Ps),
   member(P,Ps),
   [X,Y,Z]=P,      % assuming you know the format of the controlpoints to
                   % also be [x,y,z]
   nso(sphere([centre(X,Y,Z),radius(1)])),
   fail ; true.    % teehee.

   Once you get to animations and more complex objects things start to get
   more interesting.
   For example, I recently wanted to make an 800-frame animation which may,
   briefly, be described thusly:
   Flying towards the ground, a maze rise up of the ground. You enter it,
   and fly around a bit, following the physical laws (i.e. banked turns and
   whatnot). After a while, a ceiling is created above you, tile by tile.
   The tiles go from transparent to opaque (grey). You dodge some obstacles,
   have a close look at a drone flying in front of you, the ceiling fades
   back again, you leave the maze, and do a fly-by (to let you examine the
   maze from above).
   There are several interesting points here. I wanted a random maze, and
   therefore wrote a program which'd create mazes. With the programming
   interface, fer sure! This program was then run until I found a maze which
   looked perfect - no doubt a lot better than anything I could've come up
   with manually. Examining the maze I then found the 'solution' path, and
   the control points needed to steer the camera down this path. This was
   also done iteratively until I was happy with the camera-path - no flying
   too close to the walls or anything interesting like that.
   The rest - moving clouds, ceiling, raising maze &c., was relatively
   boring.
   As no 'clock' variable can cope with all that, 800 camera-files were
   then written. (i.e. '#include "maze.inc" camera ...')
   The result looks quite agreeable on VHS, now if I could only find
   mpeg_encode...
o No doubt there are other features which may be considered important - but
  I cannot recall any.
o No repetitious movement syndrome (or whatever it was called before a UK
  judge decided that there was no such thing!).

Cons....

o No mousing-interface.
  Actually, not strictly true. You _can_ use a mouse to do trivial things
  like save or zoom. But NOT to create any objects, scale/translate/rotate
  them etc.
o Awkward programming interface unless you know prolog? Generally speaking,
  if you can guess what the examples below do, you should be ok. Another
  thing - I'm not afraid of typing, so some things have been given overlong
  names.
      bspline_test :-
         clss,daso,
         new_screen_object(camera([location(80,80,80),look_at(0,0,0)])),
         new_screen_object(light_source([position( -10, 100, 100),
                                         colour(rgb(1,1,1))]) ),
         %% generate 20 control points.
         bagof( [X,Y,Z],
            I^(  between(1,20,I),
                 X is random(100)-50.0,
                 Y is random(100)-50.0,
                 Z is random(100)-50.0
            ),
            CPs
         ),
         %% make a tiny box at each control point to show what we're doing.
         forall( member(P,CPs), 
            ( [X,Y,Z]=P,
              X1 is X-1, Y1 is Y-1, Z1 is Z-1,
              X2 is X+1, Y2 is Y+1, Z2 is Z+1,
              new_screen_object(box([bc(X1,Y1,Z1),tc(X2,Y2,Z2),
                                texture(pigment(colour(rgb(1,1,1))))]))
            )),
         %% calculate the bspline points. 400 of them
         spline(b_spline,CPs,400,NPs),
         %% create 400 spheres on the bspline curve. Do it the slow way.
         forall( nmember(P,NPs,N), 
            ( [X,Y,Z]=P,
              N2 is N/400.0,
              R is N2,
              G is 1.0 - (N2*N2),
              B is N2,
              new_screen_object(sphere([centre(X,Y,Z),radius(1),
                                texture(pigment(colour(rgb(R,G,B))))]))
            )),
         save_povray2('bspline.pov').
      jade_ring :-
         daso, clss,
         new_declared('White',colour(rgb(1,1,1))),
         new_declared(camera_pos,vector(200,0,80)),
         new_screen_object(camera([location(camera_pos),
                                   sky(0,0.5,1),
                                   look_at(0,0,-15)
         ])), % camera - or had u guessed?
         new_screen_object(light_source([position(camera_pos),colour('White')])),
         new_screen_object(light_source([position(200,0,0),colour('White')])),
         new_screen_object(light_source([position(0,200,0),colour('White')])),
         new_screen_object(light_source([position(0,0,200),colour('White')])),
         new_declared(ring_sphere,object,sphere([centre(0,0,0),radius(6)])),
         new_declared(my_texture,texture,texture([
                                            pigment(['Jade',scale(2,3,4)]),
                                            finish([phong(0.7),phong_size(70)])
         ])),
         NoSpheres is 3333*3,  % Loadsa spheres
         Size1 = 15,
         Size2 = 100,
         forall(  between(0,NoSpheres,I),
            (  Phi1 is 3.0*360*I / NoSpheres,
               Phi3 is 34*360*I / NoSpheres,
               Z is Size1*degs_sin(Phi3),
               Y2 is Size2+0.5*Size1*degs_cos(Phi3),
               X is Y2*degs_sin(Phi1),
               Y is Y2*degs_cos(Phi1),
               new_screen_object(ring_sphere([translate(X,Y,Z),
                                              texture(my_texture)]))
            )
         ).
  If you can cope with those two examples you should _definitely_ be ok.
o Fast it isn't.
  As a matter of fact, for certain images it takes longer to create the .pov
  file than it does to render it.
  If I get around to use the C/C++ interface the speed should increase by an
  order of magnitude for certain operations.
  However, it is still incredibly much faster to write a tiny loop to create
  spheres than it is to do them by hand.
o Requires XPCE.
  Which is only public domain in the Linux version. It can be found
  somewhere in the netherlands, something like swi...nl.
  Beware - after I moved off the InterNet proper, I have been unable to
  update both my copy of XPCE and Linux, so I cannot guarantee that it
  works!
o Development has more or less stopped. Capov! has now reached a stage where
  I'm happy to use it, and things are only added when I find a need for it.
o It is just about conceivable that there are some bugs left... :-)


Radar
