NEW Read about the v1.4 BETA 20080930 release  NEW
By Lars C. Hassing

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

POV-Ray rendering of testcar.mpd
POV file generated exclusively from DAT files by the command
l3p -b -f -cg30,65 -ca20 -q3 testcar.mpd
POV-Ray rendering of testcar.mpd with LGEO parts
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:

POV-Ray rendering of m4555d.dat
l3p -b -f -ca40 -q3 m4555d.dat
POV-Ray rendering of m4555d.dat with LGEO parts
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:

POV-Ray rendering of m6596a.dat
l3p -b -f -q3 m6596a.dat
LDraw drawing of m6596a.dat
ldraw m6596a.dat

Here is a set from 1970, a veteran car:

POV-Ray rendering of m603.dat
l3p -b -f m603
LDraw drawing of m603.dat
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:

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" around 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 3482 Wheel Centre Large:

POV-Ray rendering of 3482.dat with primitive substitution POV-Ray rendering of 3482.dat without primitive substitution
With primitive substitution:   l3p -b1,1,1 3482 Without primitive substitution:   l3p -b1,1,1 3482 -p


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.0 19980818

I made an announcement on the L-CAD mailing list (that was before lugnet) and later a posting in rec.toy.lego: L3P - render any LDRAW model in POV-Ray

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>,
   sky      -y
   right    -4/3*x
   look_at  <-1.30431,-5.18241,-21.5678>
   angle    67.3801
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.


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.


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 POV-Ray 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 into e.g. C:\LDraw\Apps\LGEO. The LGEO directory contains 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 POV-Ray 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\Apps\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 POV-Ray upon successful writing of POV file

If you add the -pov option L3P will try to launch POV-Ray 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)
  6. The document's directory (the directory of the main model)
  1. Inside the document if it is an MPD
  2. The document's directory (the directory of the main model)
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 ...
   // 0 STEP
   #if (clock > 2)
      object { _3001_dot_dat ...
      object { _3297_dot_dat ... // [DAT lines in step 3]
      object { _6015_dot_dat ...
   // 0 STEP
   #if (clock > 3)
      object { _3001_dot_dat ...
      object { _3297_dot_dat ... // [DAT lines in step 4]
      object { _6015_dot_dat ...

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

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):

POV-Ray rendering of m6649.mpd
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
  Conditional section begin
  Begin POV statements in comment statement fields

  Conditional section begin
  Begin DAT statements

  Switch between above section modes

  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.


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.

Version 1.4 BETA 20080930

Well, more than seven years since last release... what can I say? During that time I have had several periods with concentrated development, but then something else came up and the project went on hold. Often I was close to a release, but there were always a few loose ends that I wanted to finish. Thinking about it now, it's really silly that I didn't make some smaller releases, rather than waited for all parts to fall into place. On the other hand, I quite happy that the v1.3 has proven to be rather stable and useful, with only a few bugs.

In 2005 I was revising the LGEO support, and I realized that I couldn't go on using the LGEO tab files. They lacked support for letter suffixes in part file names and I decided to make a simple text file with all the data needed by L3P to use the LGEO files. I had it all working and I was going to release in September 2007, but then I got an e-mail from Lutz Uhlmann talking about his plans for the future of LGEO. So we agreed on a new text file format and two new files (lg_elements.lst and lg_colors.lst) to replace the tab files. I rewrote the LGEO support once more while Lutz kept adding more LGEO parts. We had many fruitful discussions about closer integration of LGEO and L3P, and we are proud to present the latest development.

L3P v1.4 does not support the old LGEO files, you'll need the new LGEO files.

-lgeo  use LGEO parts and colors

L3P needs to know where it can find the two files, lg_elements.lst and lg_colors.lst, which contain info on the LGEO elements and colors. The two files are located in the directory named lgeo.
The lgeo folder
L3P looks for the lgeo directory in this order:
1. The -lgd<dir> option
2. The LGEODIR environment variable
3. Key LgeoDirectory in section [LDraw] in an ldraw.ini file.
4. Finally a couple of typical locations on the disk are checked if they exist:
$HOME/Library/lgeo     (MacOSX only)
/Library/lgeo          (MacOSX only)
/usr/local/share/lgeo  (Linux/MacOSX only)


-ar  use Anton Raves parts and LGEO colors

Lutz has added support for POV files by Anton Raves. Read more in LGEO.pdf in the lgeo directory.
You can use -lgeo and -ar together. In case a part has been made by both Lutz and Anton, the order of the options does matter: the first option specified decides which part to choose.

-nolgc[f]  don't use LGEO colors [nor finishes]

When you use the -lgeo option, you can choose not to use the LGEO colors, but rather the LDraw colors. The LGEO finishes are still used.
Specifying -nolgcf won't use the LGEO finishes either.

Colors from ldconfig.ldr

The new default for color values is to use the definitions in ldconfig.ldr located in the LDraw directory. See LDraw.org Colour Definition Language Extension.

-ldc[<path>]  alternative ldconfig.ldr or none

The -ldc option lets you specify an alternative color config file. L3P looks for the file in the current directory and in LDrawDir, or you can give a full path.
Specifying -ldc without a file means "don't use any ldconfig.ldr file" and use the old L3P colors.

Color options now also take name or #RRGGBB

Because colors are named in ldconfig.ldr L3P will now accept color names in options taking a <color>. For e.g. the background option -b<color> you can in stead of -b15 specify -bWhite.

L3P now also accepts #RRGGBB as a color.

Thus <color> is an LDraw color name or number, extended/direct color (0x0tRRGGBB), #RRGGBB or <r>,<g>,<b> in the range 0..1 like POV-Ray.

-ib<file>  include file at beginning of POV file

This option will put an include statement at the beginning of the POV file. When specifying e.g. -ibmydef.inc L3P will add the following POV code right after L3P's definitions:
//// IncludeFile AtBeginning
#include "mydef.inc"
Note that L3P merely outputs the above code; there is no check of the file. You must make sure that POV-Ray can find the file by specifying the necessary include path in POV-Ray.

-ie<file>  include file at end of POV file

This option will put an include statement at the end of the POV file.

-ic[<file>]  no camera, optional include file

This option will replace the L3P camera section with an include statement. Specifying -ic without a file will simply suppress L3P's camera code.

-il[<file>]  no lights, optional include file

This option will replace the L3P light section with an include statement. Specifying -il without a file will simply suppress L3P's light code.

Many more primitives

Several additional POV-Ray equivalents for primitive substitution have been added: stud10.dat, stud6a.dat, 1-4chrd.dat, 1-6cyli.dat, 1-16cyli.dat, 3-8cyli.dat, 1-4ccyli.dat, 3-4disc.dat, 3-4ndis.dat, 1-8ndis.dat, 1-8sphc.dat, axlehole.dat, axlehol4.dat, axlehol5.dat, axlehol6.dat, axlehol7.dat, connect.dat, connect2.dat, connect3.dat, connect4.dat, connect5.dat, arm1.dat, arm2.dat,
And for any N: 3-4rin[g]N.dat, 4-4rin[g]N.dat, 1-8rin[g]N.dat, 3-8rin[g]N.dat, 1-4conN.dat, 4-4conN.dat
And for any tube radius FFFF: t04iFFFF.dat, t04oFFFF.dat, t04qFFFF.dat, see also the thread in lugnet.cad.dat.parts.primitives Re: Torus primitive discussion.
The torus primitives were delayed waiting for my POV Torus bug fix.
peghole.dat has been removed as it is covered by ring3.dat and 4-4cyli.dat.
See also the LDraw Primitives Reference.

LDrawDir revisited

One of the greatest hassles for users unfamiliar with the command prompt / DOS has turned out to be setting the LDrawDir. Now L3P has a wide range of ways to know the LDrawDir thanks to the LDrawIni library:
1. The -ldd<dir> option
2. The LDRAWDIR environment variable
3. Key BaseDirectory in section [LDraw] in an ldraw.ini file.
4. A number of typical locations on the disk is checked if they contain subdirectories P and PARTS:
Windows      MacOSX + Linux
$HOME/Library/LDRAW     (MacOSX only)
/Library/LDRAW     (MacOSX only)
5. Finally the current working directory is checked if it contain subdirectories P and PARTS:


ldraw.ini or org.ldraw.plist

The ldraw.ini file is a Windows INI file containing configuration information.
An ldraw.ini file may look like this:
   6=<DEFPART>C:\My Own Parts
The LDrawIni library will search for an ldraw.ini file in a number of places, the first one found is used:
1. The LDRAWINI environment variable
Windows   MacOSX + Linux
  $HOME/Library/Preferences/org.ldraw.plist  (MacOSX only)
/Library/Preferences/org.ldraw.plist       (MacOSX only)
On the Mac you may as indicated above alternatively use a Property list (plist), which may look like this in the Property List Editor:

org.ldraw.plist in Property List Editor

Here is a sample org.ldraw.plist file you can download and save to the Library/Preferences directory in your home directory. Remember to change lch to your user name.


The default searching for parts used to be:
  1. Inside the document if it is an MPD
  2. The document's directory (the directory of the main model)
where LDRAWDIR is the LDraw directory. See the thread in lugnet.cad.dev Searching for parts.

However, since L3P is now using the LDrawIni library, the search can be defined by the user by specifying a number of SearchDirs. A SearchDir is an absolute path to a directory containing LDraw files, optionally prepended with some flags.
The search for parts/primitives will still begin inside the model document if it is an MPD, but after that L3P uses SearchDirs specified as follows:

1. The LDRAWSEARCH environment variable. SearchDirs are separated with a Vertical bar (|). You can set it to e.g. "<MODELDIR>|<HIDE><LDRAWDIR>\P|<LDRAWDIR>\PARTS|<LDRAWDIR>\MODELS"
2. Environment variables LDRAWSEARCH01, LDRAWSEARCH02, etc., each containing a directory with optional flags.
3. Keys 1, 2, 3, etc. in section [LDrawSearch] in an ldraw.ini file.
4. If no SearchDirs setting is found the default is:
Directory keywords
<LDRAWDIR> This keyword is substituted with the LDrawDir. Use it to specify a search directory relative to the LDrawDir, e.g. <LDRAWDIR>/P.
<MODELDIR> This keyword is substituted with the directory of the model.
<HOMEDIR> This keyword is substituted with the environment variable %USERPROFILE% on Windows and $HOME on MacOSX/Linux. Use it to specify a search directory relative to the home directory, e.g. <HOMEDIR>/MoreParts
Flag keywords
<SKIP> The search directory is skipped. Use it to un-comment a directory.
<HIDE> The directory is searched for files, but some editors may choose not to show files from this directory in lists presented to the user.
<SHOW> This keyword is ignored, as it is the default. However, you may choose to use it as an explicit opposite of <HIDE>.
<DEFPART> Files found in this directory are considered as part files, unless the header indicates otherwise.
<LDRAWDIR>/PARTS will automatically have the <DEFPART> flags applied.
<DEFPRIM> Files found in this directory are considered as primitive files, unless the header indicates otherwise.
<LDRAWDIR>/P will automatically have the <DEFPRIM> flags applied.


Improved LDraw file type detection

An LDraw file is an LDraw file is an LDraw file. However, it is important for L3P to know whether an LDraw file is a part file, because parts may be shrunk a little to have seams between bricks. Until now LDraw files from the PARTS directory were considered as parts, but this posed a problem with unofficial parts placed in the MODELS directory and with parts embedded in MPD files.
Now L3P looks at the header of an LDraw file to detect the file type.
If header detection is not possible, then files froms the PARTS directory and from a SearchDir marked with the <DEFPART> flag are considered parts.

-ldd<dir>  set LDRAWDIR, <dir> must have the P, PARTS and MODELS directories

Override the normal settings for the LDraw directory and use <dir>.

-lgd<dir>  set LGEODIR, <dir> must be the lgeo directory

Override the normal settings for the LGEO directory and use <dir>. The lgeo directory contains the files lg_elements.lst and lg_colors.lst and the directories lg and ar.

-studs0  no studs

Specify the -studs0 option to have a fast render without studs: At the beginning of the POV file in the "//// Defines" section there is a line:
#declare L3Studs = 1;  // 1=on 0=off
which can be 0 if using the -studs0 option. The parts generated by L3P test for L3Studs, e.g.

//// Part 3710.dat
#ifndef (_3710_dot_dat)
#declare _3710_dot_dat = #if (L3Quality = 0) box { <-40,-4,-10>, <40,8,10> } #else union {
// Plate  1 x  4
// Name: 3710.dat
// Author: James Jessiman
// Original LDraw Part
   #if (L3Studs)
      object { stud3_dot_dat matrix <1,0,0,0,-1,0,0,0,1,20,4,0> }
      object { stud3_dot_dat matrix <1,0,0,0,-1,0,0,0,1,0,4,0> }
      object { stud3_dot_dat matrix <1,0,0,0,-1,0,0,0,1,-20,4,0> }
   object { box5_dot_dat matrix <36,0,0,0,-4,0,0,0,6,0,8,0> }
   mesh {
      triangle { <40,8,10>, <36,8,6>, <-36,8,6> }
      triangle { <-36,8,6>, <-40,8,10>, <40,8,10> }
      triangle { <-40,8,10>, <-36,8,6>, <-36,8,-6> }
      triangle { <-36,8,-6>, <-40,8,-10>, <-40,8,10> }
      triangle { <-40,8,-10>, <-36,8,-6>, <36,8,-6> }
      triangle { <36,8,-6>, <40,8,-10>, <-40,8,-10> }
      triangle { <40,8,-10>, <36,8,-6>, <36,8,6> }
      triangle { <36,8,6>, <40,8,10>, <40,8,-10> }
   object { box5_dot_dat matrix <40,0,0,0,-8,0,0,0,10,0,8,0> }
   #if (L3Studs)
      object { stud_dot_dat matrix <1,0,0,0,1,0,0,0,1,30,0,0> }
      object { stud_dot_dat matrix <1,0,0,0,1,0,0,0,1,10,0,0> }
      object { stud_dot_dat matrix <1,0,0,0,1,0,0,0,1,-10,0,0> }
      object { stud_dot_dat matrix <1,0,0,0,1,0,0,0,1,-30,0,0> }
#end // ifndef (_3710_dot_dat)
So if L3Studs is zero you can have a faster render if you just want to have a rough sketch of the model.
See also the -q<n> Quality option.

-cra<a>  camera roll angle

The camera will be tilted <a> degrees. Default is 0 degrees (no tilt). The automatic camera positioning is still in effect.
You can change the camera roll angle later in the generated POV file by changing the L3RollAngle variable.

-csky<x>,<y>,<z>  camera sky vector

The camera will use this sky vector initially before aligning to the look_at position. The default sky vector is 0,-1,0 (-y).
This option is intended for other programs controlling L3P. If you want to tilt the camera use the -cra option in stead.
You can change the sky vector later in the generated POV file by changing the L3Sky variable.

-cpct[<p>]  percentage to move camera further back, default is 0

As described here it is often nice to move the camera a bit further away to have some space around your model. Previously you could do that by specifying a negative radius in the -cg option, or by modifying the PCT variable in the generated POV file.
Now you can also do it directly using this option. And it also works for the -cc option and for -cg with positive radius.
You can change further away percentage later in the generated POV file by changing the L3PercentageBack variable (previously PCT).

-car<ar>  camera aspect ratio

The aspect ratio of the image will be <ar>. The default is 1.333 (4/3) corresponding to images of e.g. 640x480 or 800x600. If you change the aspect ratio to e.g. 1 you must remember to select an equivalent image format e.g. 400x400, otherwise the image will look shrunk!
You can change the aspect ratio later in the generated POV file by changing the L3AspectRatio variable.

-co[<s>]  orthographic camera

The camera will be orthographic rather than perspective.
You can optionally specify a scale factor <s>. However, this is intended for other programs controlling L3P.
You can change the camera type later in the generated POV file by changing the L3Orthographic variable.
Note that this is currently not working well or at all...

-csa<a>  camera stereo angle

The default stereo camera angle is 5 degrees as described in the Stereo view section.
You can change the stereo camera angle later in the generated POV file by changing the L3StereoAngle variable.

-csl  left stereo camera

L3P now generates the following stereo camera code:
#declare L3StereoAngle = 5; // degrees
//5 degrees corresponds to a distance between eyes (stereo cameras)
//of 1/12 of distance to model.
#declare L3StereoView = 0; // Normal view
//Uncomment either two lines below to make stereo images:
//#declare L3StereoView = -L3StereoAngle/2; // Left view
//#declare L3StereoView =  L3StereoAngle/2; // Right view
This option removes the // for the left view above, so you don't have to edit the generated POV file manually.

-csr  right stereo camera

This option removes the // for the right view above, so you don't have to edit the generated POV file manually.

-lsl  shadowless lights

This option will add the POV keyword shadowless to the lights.


To increase readability of the L3P generated POV file and to help other programs parsing the POV file I have added several bookmarks at the beginning of each section in form of POV comments:
//// MegaPOV Enabling of MegaPOV
//// Defines All the #define statements
//// IncludeFile AtBeginning #include statement specified by the -ib option
//// Finishes Definition of POV finish's
//// Macros Definition of macros
//// Textures for LGEO patterned parts Special textures for LGEO
//// Color 15 White Color definition
//// Color 15 White (from lg_color.inc) Color definition
//// Color 15 White (from ldconfig.ldr) Color definition
//// Color 257 Color definition
//// Color #02FFCC99 Color definition
//// Primitive stud.dat Primitive definition
//// Part 3001.dat Part definition
//// Submodel roof.ldr Submodel definition
//// Model car.ldr Model definition
//// ModelData Bounding box and floor data
//// Floor Floor definition
//// Background Background definition
//// Camera Camera definition
//// IncludeFile Camera #include statement specified by the -ic option
//// Lights Lights definition
//// IncludeFile Lights #include statement specified by the -il option
//// ModelObject car.ldr Reference of the model
//// Statistics Some statistics as comments
//// IncludeFile AtEnd #include statement specified by the -ie option
//// End End of file
Please note that not all bookmarks may be present in a POV file.

L3P CAMERA_CALC meta command

On request from Dean Earley there is a new L3P meta command for ignoring a section of the model file when calculating the camera position/angle, but still render it in the final scene.
Note, however, that it will only work in the main model file, since L3P doesn't "walk the tree" and only uses the parts/subfiles referenced directly from the model file for automatic camera positioning.

-cpa<a>  co-planar-angle, default is 3 degrees (1 if -check)

The LDraw Standard Committee (LSC) has devised a good co-planarity check: "A quad (line type 4) must be planar, meaning that if it is split into two triangles, both triangles will be co-planar with each other. There are always two ways to split a quad into two triangles, and both must result in co-planar triangles. The triangles are considered co-planar if the angle between their surface normals is less than or equal to 3 degrees, however, an angle of less than 1 degree is strongly recommended".

The -cpa option lets you change the default maximum angle, which is 3 degrees. Warnings are only printed if warning level is 1 or above. If -check is specified, the default maximum angle is 1 degree.
The -cpa option replaces the old -det and -dist options.

-mp<v>  MegaPOV version statement

This option will enable MegaPOV. When specifying e.g. -mp1.2 L3P will add the following POV code at the very beginning of the POV file:
//// MegaPOV
#version unofficial megapov 1.2;
// The above line of POV code must be included in every include file as well,
// not just the main POV file.


-scm  StepClock only at steps in Model (not in submodels)

The -sc option generates tests for the clock variable at steps in both the model and in submodels. Use the -scm option if you only want steps in the model.

L3P variables in the POV file renamed

To avoid conflict with any POV variables (identifiers) in include files, the variables used by L3P are now prefixed with L3. Here is a list of some old v1.3 names and new v1.4 names:
QUAL         L3Quality 
SW           L3SW 
STUDS        L3Studs 
BUMPS        L3Bumps 
BUMPNORMAL   L3NormalBumps 
AMB          L3Ambient 
DIF          L3Diffuse 


-q<n>  quality level 0..4, default is 2

The Quality option now has a new level 4 which also adds studlogo on Technic studs.
Read more about the -q<n> Quality option.

-b[<color>]  background color, -b gives 0.3,0.8,1

The semantics of the -b option has changed. Previously a POV background statement was always generated, the default color being black (<0,0,0>). But since the POV default background color is black, the background statement is now only generated when the -b[<color>] option is specified. If you don't specify a color (only specifying -b) then the L3P blue (<0.3,0.8,1>) will be used.

-pp  print primitives, prints a list of the primitives having POV equivalents

Executing "l3p -pp" prints a list of the LDraw primitives that the current version of L3P can substitute with POV equivalents, see primitive substitution.

-pp -check  check all primitives in P if they have a POV equivalent

Executing "l3p -pp -check" prints a list of all primitives found in LDrawDir/P and whether they have a POV equivalent or not:
1-16cyli.dat     L3P
1-16edge.dat     irrelevant
1-4ccyli.dat     L3P
4-4ring9.dat     L3P
4-8sphe.dat      L3P
48\1-4con1.dat   L3P
48\1-4con13.dat  L3P
48\4-4ring9.dat  L3P
48\4-8sphe.dat   L3P
62 files in C:\Lars\LDraw\P\48 checked.
5-8edge.dat      irrelevant
8-8sphe.dat      L3P
arm1.dat         L3P
arm2.dat         L3P
axle.dat         L3P
axlehol2.dat     irrelevant
axlehol3.dat     irrelevant
axlehol4.dat     L3P
t04q3333.dat     L3P
t04q4000.dat     L3P
254 files in C:\Lars\LDraw\P checked.
Primitives in P: 316
POV substitutes: 237 (75%)
L3P means the primitive has a POV equivalent. irrelevant means the primitive is not relevant for L3P because it only has line type 2.

-pc  print known color names

Executing "l3p -pc" prints a list of the colors known by L3P. Be sure to specify -pc after any -ldc[<path>] option.
The colors are printed in the syntax defined in LDraw.org Colour Definition Language Extension:
0 !COLOUR Black               CODE   0 VALUE #212121 EDGE       8
0 !COLOUR Blue                CODE   1 VALUE #0033B2 EDGE       0
0 !COLOUR Green               CODE   2 VALUE #008C14 EDGE       0
0 !COLOUR Teal                CODE   3 VALUE #00999F EDGE       0
0 !COLOUR Red                 CODE   4 VALUE #C40026 EDGE       0
0 !COLOUR TransBlack*         CODE  32 VALUE #4D4D4D EDGE       0 ALPHA 128
0 !COLOUR Trans_Blue          CODE  33 VALUE #0020A0 EDGE #002266 ALPHA 128
The asterisk (*) denotes that the color was not found in the ldconfig.ldr file, but is an L3P default color.
Tip: execute "l3p -ldc -pc" to see all the original L3P colors.

LDraw lines as comments in the POV file

All LDraw lines of the model (and submodels) are passed to the POV file as comments. This is for easier navigation in the POV file as you can recognize the originating DAT lines.
It also enables you to restore a DAT file from a POV file.

//// Model car.ldr
#ifndef (car_dot_ldr)
#declare car_dot_ldr = union {
// Car
// Name: Car.dat
// Author: James Jessiman
// Original LDraw Model - LDraw beta 0.27 Archive
// Car
   // 1 0  0 0 -90  1 0 0  0 1 0  0 0 1 4315.dat
   object {
      matrix <1-L3SW/80,0,0,0,1-L3SW/12,0,0,0,1-L3SW/28,0,L3SW/6,L3SW/-7>
      matrix <1,0,0,0,1,0,0,0,1,0,0,-90>
      material { L3Color0 }
   // 1 7  0 0 -60  1 0 0  0 1 0  0 0 1 4600.dat
   object {
      matrix <1-L3SW/68,0,0,0,1-L3SW/16.06,0,0,0,1-L3SW/40,0,L3SW/3.98511,0>
      matrix <1,0,0,0,1,0,0,0,1,0,0,-60>
      material { L3Color7 }
   // 1 0  0 0 0  1 0 0  0 1 0  0 0 1 3031.dat
#end // ifndef (car_dot_ldr)


Bug fixes in v1.4

Problem with lights in submodels fixed, lights are now part of objects.

Problem with fallback color fixed (model with one element (colored))

Could not launch PovRay on file with spaces, added doublequotes

Only substitute parts/primitives, not other MPD members like 926.ldr

Support for filenames with spaces in LT1 and "0 FILE". Also support for filenames in quotes like "new car.ldr".


Windows Win32 logo   L3P (Win32) v1.4 20080930 l3p14beta.zip (113 kB)

Mac OS X Universal Binary logo   L3P (MacOSX ppc/i386) v1.4 BETA 20080930 l3p14betamacosx.zip (117 kB)

Linux i386 logo   L3P (Linux i386) v1.4 BETA 20120311 l3p14betalinux.zip (299 kB)

MS-DOS logo There is no longer a 16 bit DOS version. Let me know if you really need one.

Please enjoy and let me know what you think.

Get a Mac! Watch the Pep Rally ad ;-)

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 drawing of m646.dat
ldraw -b7 -s0.7 m646
POV-Ray rendering of m646.dat
l3p -b -f -q3 -ca45 -sw1 -bu m646

UFO Sky Surfer / V-Wing Fighter 1997, m6836.dat.
LDraw drawing of m6836.dat
ldraw -a-1,0,-1,-0.5,1,0.5,1,0,-1 -s0.67 -b1 m6836
POV-Ray rendering of m6836.dat
l3p -cg30,220 -b1 m6836 -sw0

UFO Surface Scavenger / Cyborg Scout 1997, m6818.dat.
LDraw drawing of m6818.dat
ldraw -a1,0,-1,-0.5,1,-0.5,1,0,1 -b1 m6818
POV-Ray rendering of m6818.dat
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


L3PAO by Jeff Boen (Onyx). L3PAdd-On is a graphical user interface for L3P.

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.

LGEO POV-Ray parts by Lutz Uhlmann:

Anton's Webpages by Anton Raves:

Fixed LGEO parts by Lars C. Hassing:

LDAO by Steve Bliss:

LDLite by Paul Gyugyi:

LdGLite by Don Heyse. Making LDLite portable with OpenGL.

MLCad by Michael Lachmann. The Windows CAD program.

LeoCAD by Leonardo Zide. Windows/Linux CAD program.

LDView by Travis Cobbs. Real-time 3D OpenGL viewer.

LUGNET (International LEGO Users Group Network) by Todd S. Lehman and Suzanne D. Rich
http://news.lugnet.com/cad/    CAD newsgroup

lugnet.com/cad by Todd (Suz?)

ldraw.org in general

James J memorial

L3Lab by Lars C. Hassing. Viewer/examiner.

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

To James Jessiman Memorial

To syngress.com   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>



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

Lars C. Hassing's Homepage          E-mail logo E-mail me!   (remember to delete spam blocker from e-mail address)

Valid HTML 4.01 Transitional

Last updated September 30, 2008