L3P

NEWRead about the v1.3 20010120 release  NEW
By Lars C. Hassing

L3P is a neat little console program that will produce a ready-to-render POV-file from any LDRAW model using any part.
L3P now supports the LGEO library with high quality parts designed specifically for POV:
 

POV file generated exclusively from DAT files by the command
l3p -b -f -cg30,65 -ca20 -q3 testcar.mpd

POV file generated from LGEO parts (and a few DAT files) by
l3p -b -f -cg30,65 -ca20 -q3 -lgeo testcar.mpd

Here is one of the models in the 1995 set 4555 Freight Loading Station, a racing car:
 

l3p -b -f -ca40 -q3 m4555d.dat

l3p -b -f -ca40 -q3 -lgeo m4555d.dat

Here is the 4WD car from the 1995 set 6596 Wave Master. The POV-Ray rendering is shown together with the LDraw drawing:
 

l3p -b -f -q3 m6596a.dat

ldraw m6596a.dat

Here is a set from 1970, a veteran car:
 

l3p -b -f m603

ldraw -b7 m603

Here you have the model file m603.dat. You may have a look at the Veteran car in an ad from a Swedish Disney comic magazine from 1970 scanned by Tore Eriksson. The car is to the left in the image. You may notice that I have left out the two clear headlights and added a light on top of the roof in the right side in stead. This is to check that the image is not mirrored.
 

L3P Gallery

Take a look at the L3P Gallery to see some amazing images made out of ordinary DAT files. (Sorry, not updated with images from L3P v1.3 yet)
 

The motive to L3P.

I joined the L-CAD mailing list in August 1997, after a reference in rec.toys.lego, which I read for the first time a few days earlier. I was (and still am) very excited about the existence of such programs as LEdit/LDraw and the like. Programs that I had been dreaming of for years. I started modeling some of my old simple models in LEdit, and wanted to try out Lutz Uhlmann's L2P, because I had used POV several times before. I began to make building instructions for a simple set, the 603 veteran car, in order to get to know LDRAW and L2P better. However, I was disappointed that my ray-traced model had "holes" in it, because some parts were not yet in LGEO-format (it was 3063 Brick 2 x 2 Corner Round, 7 Tyre Single Smooth and 3137 Brick 2 x 2 with Wheels Holder, which all have been added since then). Have a look at the Instructions for set 603 Veteran car.

From the FAQ, the L-CAD mailing list and various homepages I understood that LDraw was simply drawing lines and 3- and 4-edged polygons. So an obvious idea came to my mind: why not just transfer the polygons to POV? I then studied the format of the DAT-files and the meaning of the line type parameters. I began dissecting the 3004.DAT (Brick 1 x 2) and its subfiles. To ensure that my understanding of the DAT-files was correct and to play with 3D-geometry in general I actually began writing a Win95 program to read the DAT-files and display the lines and polygons in 3D. The main purpose of the display-part of the program was to test the many 3D transformations applied to the polygons, since I wanted to transfer the polygons to POV. The transformations work recursively as you follow the line type 1 inclusion of other DAT-files.

The program had many buttons to experiment with e.g. toggling the different line types on and off. It offered many different views and even let you rotate the model or part by the mouse. I did not, however, put any effort into z-buffering or hidden line/surface removal, as this was not the object of the program, so the display could sometimes be somewhat confusing because lines and polygons were just drawn in the order they appeared in the DAT-files. But it did give a good conception of the 3D geometry.

The program was called L3: when you begin a new project in Microsoft Visual C++ 5.0 you are prompted for a project name, so I just typed L3 for Lego+Ldraw+Lars :-). It was released as L3Lab in February 2000.

I then began generating the POV-files. In stead of drawing the polygons on the display, I simply wrote them to a file in POV syntax. But even for a simple 35 brick model like the 603 Veteran car the number of polygons quickly adds up: 3,400 triangles and 8,300 quads giving a total of 20,000 triangles. No wonder that LDraw may take time (and L3 too :-). So, in my first attempt the POV-file was 23,500 lines long, an overwhelming 1.7 Mega Bytes! It did, however, render relatively fast (<2 minutes for 320x240 no AA, and even <1 minute using meshes (Pentium 100MHz)). Apparently POV is very good at handling triangles.

Well, after some browsing in the POV manual I discovered the matrix keyword. In stead of feeding POV with all the transformed triangles, why not let POV take care of the line type 1 transformations? In the next attempt I made L3 convert each DAT-file into a POV object. The simplest DAT-files with only line type 3 and 4 became POV object having only triangles. DAT-files with line type 1 then became POV objects referencing other POV objects using the matrix for the transformation. The POV-file now got considerably smaller (950 lines, 49 kBytes) but took slightly longer to render (as POV now had to do the transformations itself).
 

Camera positioning, the L3 Globe

In the first 4-5 scenes I rendered of different models, I used a fixed camera position and view. However, this became unsatisfactory as the size of the models varied. Sometimes the model would just be a small object in the rendered image, and sometimes the model would not fit into the camera view. The next couple of months the project was put off and I occasionally spent some time wondering how to solve the problem. Around Christmas I had some time for the project and I had an idea. It is not easy to define a camera position in terms of x,y,z coordinates (Cartesian) and it also depends on how the model is offset with respect to the origo. So I decided to use polar coordinates. They are much easier to grasp.

The L3 program had all the information about the geometry of the parts in memory, so it knew (or rather was able to calculate) the size and position of the model. With polar coordinates (relative to the center of the bounding box of the model) I only needed to supply the viewing angles and the distance. But how should I define the two angles in an easy understandable way? The answer was right below my feet: the Earth. We all know the globe and the Latitude and the Longitude. Think of a model placed inside a globe, with the center of the model's bounding box placed at the globe's center. You can now easily place camera (and light sources) in the 3D space by specifying Latitude, Longitude and Radius.

The L3 Globe. Click to see a larger version.
The L3 Globe. Click on the globe to see it in 1024x768 (265 kB). Download the POV source code l3globe.zip (10 kB).

L3 uses LDraw's coordinate system and measures. The floor is parallel to the XZ-plane and Y is negative upwards. Latitude is in the range from -90 degrees (south, along the positive y-axis) to 90 degrees (north, along the negative y-axis). 0 degrees is at the equator.
Longitude is in the range from -180 to 180, where 0 degrees is along the negative z-axis. 90 degrees (east) is then along the positive x-axis and -90 degrees (west) is along the negative x-axis.
The basic LDraw views can be represented by these Latitude,Longitude pairs:
Front=0,0 Right=0,-90 Left=0,90 Back=0,180 Over=90,0 Under=-90,0.
The 3D view can e.g. be 45,45 or 30,45.

But what about the camera distance, the Radius? I really wanted just to specify the viewing direction (Latitude,Longitude) and then have the camera to be "as close as possible" in order to minimize the space around the rendered model. So I devised the following algorithm:
 

  • Think of the camera view towards the model as a funnel or a pyramid.
  • Rotate the pyramid so that its centerline is parallel to the viewing direction vector.
  • Then move the pyramid towards the model until it cannot come any closer.
  • Now you have the camera position as the location of the top of the pyramid.
  • The viewing direction vector will be parallel to the direction given by (Latitude,Longitude) but not necessarily through the globe's center (which is the same as the model's center). To avoid problems with irregular shaped models I used all the bounding boxes of the parts when checking against the pyramid, rather than the total bounding box of the model, which can be "too big". (Ideally all triangles and quads should be considered, but in order to speed up calculation and reduce memory usage the program just fits the bounding boxes of the parts in the model into the camera view, i.e. one level of bounding boxes. (This has, however, turned out to give some problems with irregular shaped sub models, which are just treated as ordinary parts. If it becomes a real nuisance, I might use more levels some day. But often you won't use the closest view anyway, see later)). Some "space" will always exist either horizontally or vertically to maintain the aspect ratio. The calculations turned out somewhat comprehensive and involve solving six equations with six unknowns, but they worked just fine.

    The camera position calculation worked well, almost too well: the rendered images might now look a bit distorted (some fish-eye effect), when the camera was moved that close; but remember the object was to minimize the waste of empty rendered area. However, to get a nicer looking image (and a better look at the shadows) it could actually be advantageous to have some "space" a round the model. I obtained this by moving the camera away again from the model along the direction vector. Depending on your taste and the model, you get nice images when moving the camera 5-20% further away (5-20% of the calculated closest radius). After generating the POV-file you can continue experimenting with the camera distance (without generating a new POV-file) simply by editing the line near the end of the file:

       #declare PCT = 20 // Percentage further away
    and do another rendering. I use POV-Ray for Windows and it has an editing window with the POV-file and buttons for starting/stopping the rendering. You can easily experiment with the POV-file and do some fast, low resolution renderings for previews, before starting the high resolution with anti-aliasing etc.

    The positions of the light sources may also be specified as globe coordinates (polar coordinates), but these are always relative to the center of the bounding box of the model (and not to the point that the camera is looking at, as this point may be offset when you choose the closest camera view): if you want to make an animation I think it would be better to place the lights relative to the model than to a more or less random camera look-at-position.
     

    Primitive substitution

    Now I could render my models with a nice, almost automatically set view. But the studs and the round parts looked a bit edged or angular. Of course they did, all parts are composed of triangles and quads. So the next idea to try out, was to replace some of the round/curved primitives in the P directory with POV equivalents, e.g. to replace the 16 quads in 4-4cyli.dat with the perfectly round POV object "cylinder { <0,0,0>, <0,1,0>, 1 open }". This was a great progress. The images improved very much. L3 generated smaller POV-files and they even rendered 10% faster. Currently 33 (plus all rings and cones) of the most used primitives have POV equivalents. You can see which by executing "l3p -pp".

    However, I ran into a bug in POV-Ray: the disc object did not render correctly. I made a request to comp.graphics.rendering.raytracing and Vahur Krouverk from Estonia was very helpful and examined the POV source code (which is public available) and pointed out the bug ("matrix transformation for disc does not modify disc's normal vector and therefore it gets coloured differently") which was reported to the POV-Ray development team. The error has been fixed in v3.1, but to support older versions L3P can also use a very thin cylinder rather than the disc.

    There is one drawback using the primitive substitution. Some complex parts interface the primitives by drawing triangles and quads up to the edges of the primitives. When a 16-edged cylinder is then replaced by a perfectly round cylinder, you get "holes" in the part. E.g. the 6246d Minifig Tool Box Wrench:

    Finishes

    Several times during the development of the L3 program I have changed the colors and the textures/finishes in the POV-files. In the very beginning I simply used the LDraw colors. I made a model with all 16 colors, made a .BMP file using LDraw, and noted the 16 RGB values in a paint program. Later I changed the colors to match some scans I did of some of my real bricks. But no matter which colors you choose, the final colors in the rendered image will depend heavily on the light sources and the material properties you select.

    I think that choosing the right colors, textures and light sources is the most difficult task in rendering. The colors and textures used today in L3 are empirical values from many experiments. I am not completely satisfied and would like to hear any suggestions. Currently I use the same RGB color for normal bricks and for transparent bricks. But this does not seem to hold for all colors, e.g. color 2 (green) and color 34 (transparent green) should use two different sets of RGB values. Also it is difficult to determine the amount of ambient light and the number of light sources. If you use little ambient light bricks not directly lit become too dark, and if you use more ambient light especially white bricks tend to get "overexposed".
     

    Publishing my efforts

    Well, I eventually became quite content about the POV-files that L3 generated. So I would like to share my results with the LDraw community. However, the non-POV portion of the L3 program was not something that was ready for release, so I decided to extract the POV portion into a small self-contained program, a sort of a spin-off of the L3 project. As mentioned before L3 was developed in Microsoft Visual C++ 5.0, but I still often use my years old, but fully functional, Borland Turbo C 2.0 for quickly making small programs. So I rearranged the L3 source files, added a lot of #ifdef's, checked for 16-bit variables and far (!) pointers and made a command-line interface program that included some of the L3 source files, and L3P was born. L3P runs under DOS or in a DOS-box in Windows95/WindowsNT. It is a 16-bit application and thus needs no DOS extenders.
     

    Version 1.1 19990114

    Well. I have received a lot of kind mails from all over the world, thank you all, and I have enjoyed the many discussions in the newsgroups and mailing lists. Among the almost fulsome praises (blushing, but don't stop ;-) were a lot of good suggestions and ideas. This has led to several improvements of L3 and L3P. I actually programmed most of them back in September, but since then I have had a hard time to find enough spare time to test thoroughly and to make the web pages. There is often a long way from implementing a new feature and seeing that the basic idea works, to the completion of the feature covering all cases. But in the last few weeks I have put an effort into making this new release ready before Christmas to share the new features with you. So here it is:

    Quality Level control

    Reduce the quality level of the rendered scene to substantially speed up test renderings. Or add the icing of the cake, or rather the studs ;-)
    Read more about the -q<n> Quality option.

    Seams between bricks

    To have more realistic renderings L3P can make a little space between the bricks. Until today you couldn't tell where in the POV-Ray renderings one brick ended and the next brick (with same color) started.
    Read more about the -sw<w> Seam Width option.

    Camera Viewing Angle

    By varying the camera angle you can increase the 3D perspective distortion (more fish-eye effect), or you can obtain almost isometric renderings.
    Read more about the -ca<a> Camera Angle option.

    Stereo view

    By rotating the camera slightly to the left and then to the right you may render two images as viewed from your two eyes. By looking at the stereo pair images in a stereo viewer (some people can adjust their eyes without one) you will experience a true 3D image with depth. L3P will generate the following camera code:
    // Camera (Latitude,Longitude,Radius = 30,45,0)
    camera {
       #declare PCT = 0; // Percentage further away
       #declare STEREO = 0; // Normal view
       //#declare STEREO = -degrees(atan2(1,12))/2; // Left view
       //#declare STEREO =  degrees(atan2(1,12))/2; // Right view
       location vaxis_rotate(<117.841,-102.464,-140.713> + PCT/100.0*<119.146,-97.2821,-119.146>,
                             <-11590.7,-28391.4,11590.7>,STEREO)
       sky      -y
       right    -4/3*x
       look_at  <-1.30431,-5.18241,-21.5678>
       angle    67.3801
       //orthographic
    }
    By removing the appropriate comment slashes (//) you may render either the left or the right image.

    A good distance between the eyes is one twelfth of the distance from the eyes to the model (the look_at point). 1/12 corresponds to an angle of 4.8 degrees. You may vary this by replacing 12 with other values (e.g. in the range 5 to 20) in the atan2() function to obtain more or less depth in the scene.

    Bumps

    Sometimes a model may look a bit transparent, but this is really reflections of other parts in the perfect geometric/symmetric world of Lego. Until I get the gallery updated you may see the problem in e.g. Villa Roma. As you might have noticed in the L3P Gallery I have tried to keep my models below the horizon. But now L3P can simulate the slightly bumpy texture you can see when you look along a 1x8 Lego brick and you notice that the heating/cooling of the molding has made the brick slightly uneven/bumpy. (Or like what you see if you look down the side of a ship/ferry and you can see that the side is put together from a large number of not totally plane steel plates.) Use the -bu option to turn on the bumpy surface. It simply sets the initial value of the BUMPS variable in the POV code.

    POV-Ray v3.1 compatible code generation

    I was rather astonished when I in November downloaded POV-Ray for Windows v3.1 and rendered a model for the first time. There were several warnings in the log. Although I had received a lot of mails about L3P and followed the discussions on the Internet, I hadn't heard a single remark about these warnings.

    One of the most important new features in v3.1 is that texture is now replaced by material which comprises both interior and texture. Some features like refraction and ior (index of refraction) has been moved from texture to interior, which is really logical: texture is for the surface of an object, interior is for the - yes - interior.

    By the use of the #if directive, L3P now generates POV code that runs without any warnings on both v3.0 and 3.1. If you experience a burp from POV, please let me know.

    Support for MPD files

    L3P can directly read multi-part LDraw files (MPD files). A multi-part LDraw file shall contain a FILE meta-command at the start of each file. The format of a FILE meta-command is "0 FILE somefile.dat". This saves you the process of splitting an MPD file before rendering it. Read more about MPD in the LDraw FAQ. L3P Version 1.1 19981221 complained about the header lines before the first FILE meta-command.

    File search also in directory of model

    LDraw searches for DAT files in four places: in the current directory, in the P directory, in the PARTS directory and finally in the MODELS directory. L3P will now also look for files in the directory of the model file. This is convenient if you e.g. keep a model and some submodels in a separate directory.

    Unlimited number of light sources + option to add default light sources

    The number of light source was in version 1.0 limited to 20 for my programming convenience. Now you can have as many as you like. Also there is a new option -ld to always load the three default light sources no matter if you have included some light.dat in your model.

    11 new primitives

    Additional POV equivalents for primitive substitution: ring1.dat, ring2.dat, ring3.dat, ring4.dat, ring7.dat, ring10.dat, 2-4ring3.dat, axle.dat, 4-4con12.dat, 1-4con3.dat, 1-4con4.dat
     
     

    Version 1.2 20000616

    Well, it's been more than a year since the last official L3P release. Mainly because I have spent more time on L3Lab. But nevertheless several nice features have been added during that time.
    So here it is:

    STUDS flag in POV file

    Turn off studs to substantially speed up test renderings.

    TRANSLATE, ROTATE, SCALE, TRANSFORM meta commands

    L3P now handles these meta commands suggested by Paul Gyugyi and used in e.g. Minifig Modeller in Steve Bliss's LDAO.

    -c=<color> Default Part Color

    Normally the model contains colored references to parts, but if you only want to render a single part, the part typically uses the color 16 for its subparts and primitives, and the part would just be rendered in the default gray color (7). You would have to create a dummy model file with just one line, like
       1 4  0 0 0  1 0 0  0 1 0  0 0 1 3001.dat
    to render the part 3001 in red (4).
    However, this option lets you specify the default part color for color 16 references, and you can simply start L3P like this:
       l3p -c4 3001

    LDRAWDIR or ldraw.ini

    It is no longer necessary to set the environment variable LDRAWDIR if you are using LDAO or LDLite. If LDRAWDIR is not set, L3P looks for ldraw.ini in C:\Windows (or the directory specified by the environment variable WINDIR). If found, L3P uses the BaseDirectory setting in the [LDraw] section.

    Extended colors (direct colors)

    The LDraw colors are 0-15, 32-47, 256-511 (and of course 16 and 24). Paul Gyugyi defined some more colors for LDLite: 17-23, 25, 57 and "Direct Colors" in the range 0x04000000-0x07FFFFFF.

    As MLCad also supports these colors, L3P does too.

    However, Gyugyi packed two RGB's (for dithering) into each Direct Color leaving only 12 bits to each RGB, e.g. 0x04RGBRGB. Some L3P and L3Lab users have asked for the possibility to specify "true colors" (24 bit RGB's), so I have defined the range 0x02000000-0x03FFFFFF for this. 0x02RRGGBB for solid colors and 0x03RRGGBB for transparent.

    I will support, but not require, hex notation for colors (0x/0X prefix). You are welcome to specify the color value in decimal ;-)

    The following description is partly taken from the LDLite documentation:

    3. Direct colors
    LDLITE defines the color values from 0x4000000 to 0x7ffffff. These represent two 12-bit colors which are dithered together, and cannot be redefined. They are intended to be used in converting meshes from other 3D formats. While you can use decimal numbers, the hex representation makes the structure clear. The edge color for all direct colors is pure black.

    The first (leftmost, most significant) hex digit defines whether the color will be transparent. "4" is an opaque color. "5" or "6" create transparent colors. "7" will create an invisible color which will not be drawn at all. You can interpret the two least significant bits of this digit as inverted alpha values.

    The second, third and fourth digits are the red, green and blue intensities of the first dithered color. These digits are ignored for colors in the range 0x6000000 to 0x7ffffff.

    The fifth, sixth and seventh digits are the red, green and blue intensities of the second dithered color. For pure colors, set these to the same as the second, third and fourth digits. These digits are ignored for colors in the ranges 0x5000000 to 0x5ffffff and 0x7000000 to 0x7ffffff.

    Note that this is the correct description! Paul Gyugyi has swapped the hex ranges in the last two paragraphs in his LDLITE documentation!

    Valid colors

    L3P now knows these colors (apart from 16 and 24):
    0-15, 17-23, 25-28, 32-47, 57, 256-511, 0x02000000-0x07FFFFFF.
    Color 256 is used for black rubber.

    I haven't spent any time adjusting the new LDraw colors, they were just added from the FAQ. But I'll play a little with POV again to make some better colors. Most importantly the transparent colors should not necessarily be based on the corresponding non-transparent colors, but may have their own RGB values.
    Please make any suggestions.

    In the POV file an "#ifndef ColorXX" / "#end" pair is now put around L3P's color definitions. This makes it easier to use your own definitions.

    Unlimited number of colors

    The number of simultaneous colors was in version 1.1 limited to 200 for my programming convenience. Now you can have as many as you like. I haven't heard about anybody reaching the limit yet, but with the introduction of extended colors, the number of different possible colors is now huge.

    14 new primitives

    Additional POV equivalents for primitive substitution: 1-4cyls.dat, 1-4cyls2.dat, 2-4cyls.dat, 3-8cyls.dat, 2-4ring1.dat, 1-8disc.dat, 4-4con1.dat, 1-4con1.dat, 1-4con2.dat, 1-4con10.dat, 1-4ring1.dat, 1-4ring3.dat, 1-4rin10.dat, 1-4rin14.dat

    Support for hi-res primitives

    Primitives in P\48 and future numeric subdirectories of P are also supported. L3P skips any digit-only directory before attempting primitive substitution, and thus treats e.g. 48\1-4cyli.dat exactly like the ordinary 1-4cyli.dat

    More checks

    L3P now detects recursion, i.e. subparts referring each other in a ring.

    Many parts actually have identical lines. Probably because of copy'n'paste blunders by the author, or because the same line or surface was simply coded twice in the file. Since this is a waste of rendering time, L3P can now report such repeated lines. The DOS version of L3P just reports that a given line has been seen before, the Win32 verson also shows you the line number of the previous occurrence.

    Another common mistake is to reference lines with color 16 instead of color 24, so L3P now warns about this. The only legitimate example I have seen is in PARTS\S\973p46a.dat.DAT "~Subpart Minifig Torso with Forestman and Purse Pattern" by Chris Dee where he used color 16 linetype 2 to make sure an outline is visible at low resolution, see also http://news.lugnet.com/cad/dev/?n=4161 and http://news.lugnet.com/cad/dev/?n=4248. A clever but questionable technique because it makes some assumptions about the renderer. All other examples I have seen are errors, and that justifies the "Lines should not use color 16" warning.

    Ill-formatted lines like "01 ..." are also noticed.

    Bad lines before first valid commands are now allowed. You should now be able to directly render e.g. a DAT or MPD file sent by mail without complaints about the mail header.

    L3P -check now checks (recursively) if all subfile references can be found.

    -stdout  Redirect stderr to stdout

    Normally error messages go to stderr, but you can have them redirected to stdout by placing this option as the very first argument after l3p.
    Mainly of interest for other programs which call L3P.
    L3P will exit with 0 after a normal and successful run.
    L3P will return a non-zero exit code in case of errors.
     
     

    Version 1.3 20010120

    As you can read in The motive to L3P it was Lutz Uhlmann's LGEO library (or rather its incompleteness) that inspired me to get started in the LDRAW business. It resulted in my L3 (Lego+Ldraw+Lars) project, which has spun off L3P and L3Lab. The whole idea of L3P was to generate the missing parts on the fly. However, as it turned out that L3P could generate all parts with a reasonable result, I decided to release it before taking the next natural step of using the LGEO parts.

    Back in August 1999 Lutz Uhlmann agreed that L3P could reference his high quality LGEO POV parts. He promised to send some info regarding the binary format of the element table files. However, I have not heard from him since then, despite several mails.

    But since he did consent that L3P could reference the LGEO parts, and since many users have requested it, I've decided to update L3P now anyway. So, with a little hacking I've managed to tweak L3P to use LGEO parts whenever possible. The missing parts are generated on the fly like today.

    You now get the best of both worlds: high quality POV parts and L3P's support for automatic camera positioning, primitive substitution, MPD files, TRANSLATE, ROTATE, SCALE, TRANSFORM meta commands, extended colors (direct colors), etc.

    Besides the LGEO support several nice features have been added, read on:

    Support of LGEO parts

    To use the LGEO parts you must do three things: 1) download the LGEO parts, 2) tell L3P where they are located, and 3) tell PovRay where they are located.

    Like LDRAW, LGEO also has a set of primitives. Non-LGEO parts generated on the fly will use some of the LGEO primitives rather than the L3P primitives (POV equivalents).
    Currently the following are used:
       stud.dat    lg_knob
       stud2.dat   lg_tech_knob
       stud4.dat   lg_plate_cylinder
    Additionally the L3P studlogo is dynamically added to lg_knob, so it appears on LGEO parts too when rendering with -q3 (QUAL=3), see the -q<n> Quality option.

    I found out that we (mis)use stud4.dat by scaling its height by 5 in bricks! (and other factors in other parts). LGEO uses lg_plate_cylinder and lg_brick_cylinder and we should use two different studs in LDraw too.

    Primitive primitives (grin) like cylinders and discs are OK to be scaled, but studs should never be scaled - or they cannot be substituted correctly...
    The stud4.dat's in 3001.DAT (Brick 2 x 4) look funny now, because the rounded corner gets scaled by 5...
     

    1) You can download the LGEO parts library here. The latest part seems to be from September 23 1999, but there are 842 parts.
    Install (extract) the LGEO files to your harddisk in e.g. c:\LDraw\L2P. There will be a subdirectory named LGEO containing the POV .inc files (include files) and some table files .tab meant for L2P.
    Some LGEO files have bugs so you should also get the latest set of fixed LGEO parts from here.

    2) L3P needs to know where it can find the three files, L2P_ELMT.TAB, L2P_COLR.TAB and L2P_PTRN.TAB, which contain info on the LGEO elements, colors and patterns. The three files are typically located in the directory named LGEO.
    You can tell L3P where the LGEO directory is located either by setting the environment variable LGEODIR or by adding a line to ldraw.ini.
    If LGEODIR is not set, L3P looks for ldraw.ini in C:\Windows (or the directory specified by the environment variable WINDIR). If found, L3P uses the LgeoDirectory setting in the [LDraw] section. L3PAO can handle this for you.

    3) You must also tell PovRay where to find the LGEO include files: in POV-Ray for Windows v3.1 select "Edit Settings/Render" in the "Render" menu. Then type +Lc:\LDraw\L2P\LGEO in the "Command line options" box and click the "Set but don't Render" button.

    Now you should be all set to take advantage of the high quality LGEO parts. I've tried to overcome some of the bugs in L2P and in the LGEO parts. Also transparent LGEO parts are scaled a little bit to avoid coincident surfaces. The QUAL flag is supported to substantially speed up test renderings, see the -q<n> Quality option.
    The LGEO colors are darker than L3P's colors. You can add extra light sources if you want.
     

    -cla<x>,<y>,<z>  Camera look_at Coordinates

    The camera will look at <x>,<y>,<z> rather than at the center of the model's bounding box.
    This option only works if you also specify the camera's location, either by an absolute position using -cc<x>,<y>,<z> or by a relative position (relative to the new look_at position) using -cg<la>,<lo>,<r> where r > 0.
    The -cla option doesn't affect light sources.

    -pov  Launch PovRay upon successful writing of POV file

    If you add the -pov option L3P will try to launch PovRay with the POV file just generated. L3P simply runs "start povfile.pov" which works on at least Windows 98 and NT, I haven't tested others.
    This also works for other extensions than .pov; if you run "l3p model result.txt -pov" L3P will launch Notepad with result.txt.

    -upd  Check L3P's homepage for newer version

    If you run "l3p -upd" it will launch your Internet Browser with a special page, where you can read if you have the latest version. No automatic update takes place, you'll have to download a newer version manually, but of course you'll find links to the newest version.

    Vast number of new primitives

    Additional POV equivalents for primitive substitution: stud6.dat,
    And for any N: ringN.dat, rinN.dat, 1-4ringN.dat, 1-4rinN.dat, 2-4ringN.dat, 2-4rinN.dat, 1-4conN.dat

    New search path

    The search path for DAT files has been changed from
      1. Inside the document if it is an MPD
      2. The current directory (from where L3P is started)
      3. %LDRAWDIR%\P
      4. %LDRAWDIR%\PARTS
      5. %LDRAWDIR%\MODELS
      6. The document's directory (the directory of the main model)
    to
      1. Inside the document if it is an MPD
      2. The document's directory (the directory of the main model)
      3. %LDRAWDIR%\P
      4. %LDRAWDIR%\PARTS
      5. %LDRAWDIR%\MODELS
    where LDRAWDIR is the LDraw directory.

    See the thread in lugnet.cad.dev Searching for parts.

    -sc  StepClock, add "#if (clock > n)" at steps

    The -sc option is for those who want raytraced instruction images. L3P can support POV-Ray's built-in animation capability by testing the clock variable at steps in the model: L3P will identify "0 STEP" lines and insert conditionals like this:

          object { _3001_dot_dat ...
          object { _3297_dot_dat ... // [DAT lines in step 1]
          object { _6015_dot_dat ...
       // 0 STEP
       #if (clock > 1)
          object { _3001_dot_dat ...
          object { _3297_dot_dat ... // [DAT lines in step 2]
          object { _6015_dot_dat ...
       #end
       // 0 STEP
       #if (clock > 2)
          object { _3001_dot_dat ...
          object { _3297_dot_dat ... // [DAT lines in step 3]
          object { _6015_dot_dat ...
       #end
       // 0 STEP
       #if (clock > 3)
          object { _3001_dot_dat ...
          object { _3297_dot_dat ... // [DAT lines in step 4]
          object { _6015_dot_dat ...
       #end
       :
       :

    L3P will print out the number of steps in the model, e.g. 8. You can now generate the instruction images by:

       wine -- L3P.EXE -sc -o car.dat
       povray +I car.pov +O car.png +FN +W400 +H300 -J +KFI1 +KFF8 +KI1 +KF8 +D +A

    The output images will be named car1.png, car2.png, ..., car8.png.

    The StepClock option was added on suggestion from Fredrik Glöckner, who supplied the command lines above. He said: "These are UNIX style command line options. I really have no idea what this looks like in the Windows world. Check the manual."

    New rubber color

    While awaiting the discussion about "0 TEXTURE RUBBER" another rubber color has been added: color 375 (256+16*7+7) is used for grey rubber.
    Color 256 (256+16*0+0) is still used for black rubber.

    l3p -check

    Model title (first comment in DAT file) and Author now printed when in check mode.

    Color 24

    The only instance of a linetype 1 with color 24 was the neck-mark of the minifig torso. POV has no notion of a "reverse" color when you reference another object. Or when you inherit a color (linetype 3 and 4). And neither have other programs that you export DAT files to.
    The mark has now been removed and added in the correct color to each decorated torso.

    So, color 24 is now considered illegal for linetypes 1,3 and 4, see the thread in lugnet.cad.dev Colour 24 in non type-2 lines (was Updated S\973S01.DAT).

    Conditional POV code generation

    I have taken the liberty to introduce 4 new keywords to the DAT file format:
       0 L3P IFPOV
       0 L3P IFNOTPOV
       0 L3P ELSEPOV
       0 L3P ENDPOV

    I had been playing with the idea of embedding POV code in the DAT files since 1998. It was triggered by the 2473 Brush Car Wash, which unfortunately uses lines. This is poor design, it should have used cylinders, which will look correctly if you zoom in.
    For rendering the 6649 Street Sweeper I converted the lines to POV cylinders and it now looked like this (new LGEO rendering, but still with 2473 generated on the fly):


    l3p -b -f -cg22,135 -ca45 -lgeo -q3 m6649.mpd

    You can have a look at the POV-friendly 2473 Brush Car Wash in the model file m6649.mpd and in the thread in lugnet.cad.ray Re: Is there some pov-ray friendly version of car wash brush part?.

    However, I was reluctant to put it into L3P, because I believed LGEO was the proper solution to this kind of problem. But after several mails, Chuck Sommerville made me put into L3P v1.2 - unofficially though.
    The POV code embedding can however supplement LGEO and find use in many cases, so I hereby announce it. I think Chuck Somerville has explained it rather well in a lugnet.cad.ray posting, so with kind permission from him I'll quote him on the subject:
    From the thread in lugnet.cad.ray L3P user primitive substitution:

    Awhile back, I persuaded Lars Hassing to add a feature to L3P. I wanted the ability to substutite POV language commands in the comments of a .DAT file that could be used in place of the DAT primitives when rendering through POV. This would allow users to add native POV commands that could render better than the triangles and polygons defined in DAT files. Since the commands are inbedded in comment fields, and only recognized by L3P, they have no effect of any other tools. Lars was waiting untill I tested the commands to announce the feature. The good news, is you probably already have the ability to use these features. He built them into Version 1.2 20000616.

    The commands are
    0 L3P IFPOV
      Conditional section begin
      Begin POV statements in comment statement fields

    0 L3P IFNOTPOV
      Conditional section begin
      Begin DAT statements

    0 L3P ELSEPOV
      Switch between above section modes

    0 L3P ENDPOV
      Terminate conditional section

    After running L3P, you can see in the POV file conditionals like if(0) or if(1)
    To see the alternate version for comparison, just change the constant in these conditionals.

    If you don't understand any of this, don't worry, I am following this post up with some examples. Remember to get L3P V1.2 or latter to use thse.

    -Chuck

    L3P still produces the normal object references and meshes in an IFNOTPOV section, but puts a conditional around it.

    -enp  exclude non-POV code generation (L3P IFNOTPOV)

    Chuck Sommerville requested another option to suppress the unused .dat commands when using the L3P IFPOV commands. He likes the idea of his POV files getting smaller as well as better ;-)
    So, the -enp option will leave out the normal object references and meshes in an IFNOTPOV section, as well as the conditionals.
    See also the thread in lugnet.cad.dat.parts.primitives Re: missing lego-cad primitive: 1-4ring5.dat (modified - POV).

    Bug fix

    Only make seams if part is not scaled. If a part was exceptionally scaled the seams became too large.
     
     

    Download

    Go to the Windows logo Windows and MS-DOS logo DOS download page and download the zipped program l3p.exe and the documentation l3p.txt.
    Linux logo Linux (i386) and MacOSX logo Mac (OSX) users can go to this download page and download zipped versions for their platforms.
    Please enjoy and let me know what you think.
     
     

    More examples

    Here are some more examples showing how easy it is to use L3P.
    Be sure to visit the L3P Gallery to see some very nice POV images generated by L3P.  (Sorry, not updated with images from L3P v1.3 yet)



    Mobile office 1971, m646.dat. See Tore's scan of an ad.

    ldraw -b7 -s0.7 m646

    l3p -b -f -q3 -ca45 -sw1 -bu m646


    UFO Sky Surfer / V-Wing Fighter 1997, m6836.dat.

    ldraw -a-1,0,-1,-0.5,1,0.5,1,0,-1 -s0.67 -b1 m6836

    l3p -cg30,220 -b1 m6836 -sw0


    UFO Surface Scavenger / Cyborg Scout 1997, m6818.dat.

    ldraw -a1,0,-1,-0.5,1,-0.5,1,0,1 -b1 m6818

    l3p -cg35,-15 -b1 m6818 -sw0


     

    My LDRAW parts

    Have a look at my LDRAW parts.
     

    Parts Catalog

    When using LEdit/MLCad I find this shortform visual catalog indispensable:
    Printable Visual Parts Catalog (MS Word or HTML) by Patrick Sayre-Little
     

    Links

    L3PAO by Jeff Boen (Onyx). L3PAdd-On is a graphical user interface for L3P.
    http://l3pao.malagraphixia.com
    http://www.ldraw.org/download/win/l3pao

    POV-Ray. The Persistence of Vision Raytracer is a high-quality, totally free tool for creating stunning three-dimensional graphics. It is available in official versions for Windows 95/98/NT, DOS, the Macintosh, i86 Linux, SunOS, and Amiga. The source code is available for those wanting to do their own ports.
    http://www.povray.org

    LGEO PovRay parts by Lutz Uhlmann:
    http://www.el-lutzo.de/lego/lgeo.html.

    Fixed LGEO parts by Lars C. Hassing:
    http://www.hassings.dk/l3/lgeofix.html

    LDAO by Steve Bliss:
    http://home.earthlink.net/~steve.bliss/ldao/
    http://www.ldraw.org/download/win/ldao

    LDLite by Paul Gyugyi:
    http://www.gyugyi.com/l3g0/ldlite/
    http://www.ldraw.org/download/win/ldlite

    LdGLite by Don Heyse. Making LDLite portable with OpenGL.
    http://ldglite.sourceforge.net
    http://www.ldraw.org/download/win/ldglite

    MLCad by Michael Lachmann. The Windows CAD program.
    http://www.lm-software.com/mlcad/
    http://www.ldraw.org/download/win/mlcad

    LeoCAD by Leonardo Zide. Windows/Linux CAD program.
    http://www.leocad.org
    http://www.ldraw.org/download/win/leocad

    LDView by Travis Cobbs. Real-time 3D OpenGL viewer.
    http://home.san.rr.com/tcobbs/LDView/
    http://www.ldraw.org/download/win/ldview

    L3Lab by Lars C. Hassing. Viewer/examiner.
    http://www.hassings.dk/l3/l3lab.html
    http://www.ldraw.org/download/win/l3lab

    L3P by Lars C. Hassing
    http://www.hassings.dk/l3/l3p.html     Download Area: http://www.hassings.dk/l3/l3p.html#download
    http://www.ldraw.org/download/win/l3p
     

    To James Jessiman Memorial
     
      LEGO Software Power Tools, Including LDraw, LPub, and Ledit by Miguel Agullo and Kevin Clague.
    Covering applications such as LDraw, MLCad, LeoCAD, L3P, POV-RAY, BlockCAD, Ldglite, LDAO, and Lpub.

    Though my name appears on the front page (as a Technical Reviewer) I only reviewed Chapter 8 L3P and POV-Ray.
    Full credit for the book goes to the two authors Kevin Clague and Miguel Agullo.

     

    Put a link to L3P on your page

    Please include a link to this L3P main page at www.hassings.dk/l3/l3p.html on your own website.
    You may use this banner:
    To L3P homepage at www.hassings.dk/l3/l3p.html
    Save the image and put the following HTML code on your page:
    <a target="_top" href="http://www.hassings.dk/l3/l3p.html"><img border=0 hspace=0 vspace=0 width=88 height=31 src="l3pbanner.gif" alt="To L3P homepage at www.hassings.dk/l3/l3p.html"></a>

     

    DISCLAIMER

    This site is not affiliated in any way to The LEGO Group.
     

    Lars C. Hassing's Homepage

    Last updated January 20, 2001