BFC

From LDraw.org Wiki
(Redirected from BFCing)

BFC is the abbreviation for Back Face Culling.

That is a term from computer graphics: It describes a mechanism which assigns an orientation to a surface, i.e., which side is "front" and which side is "back".

A software for 3D rendering can use that information to speed up its computations and renderings.

Read on to understand the details.

Orientation of Triangles and Quads: Which Side is "Front", and Which is "Back"?

In our LDRAW world, we have triangles and quads. Imagine such a triangle or quad in 3D space. It is infinitely thin, but has 1 front side and 1 back side. The question is: which side is front, and which is back? The choice is arbitrary, we just have to make a clear definition. The one chosen in LDRAW is: follow the sequence of corner points in the order they are written in the LDRAW files and let the 4 fingers of your right hand follow these points in 3D space. Then your erect thumb points to a certain direction. That side of the surface shall be called "front", the other side "back". (We could have chosen just the opposite definition - as said, the choice is arbitrary.) By using this simple definition, a clear and unique "side naming" is applied to such a triangle (or quad). If you reverse the sequence of corner points, then your thumb will point to the opposite direction. Thus, by reversing that sequence, the orientation of such a surface can be "flipped", meaning that the former "front" becomes "back", and the former "back" becomes "front".

Counter-Clockwise and Clockwise

The above description of the definition of a "front" and "back" side is difficult to remember without a clear name. LDRAW historically has found 2 easy-to-remember names for the orientation definition of "front" and "back": If you take an example triangle, put it into the X/Y plane, look at it from -Z direction to Z direction, and follow its points in COUNTER CLOCKWISE order, then by the above definition you will be looking at the FRONT of that triangle. That's why LDRAW chose the name "COUNTER CLOCKWISE BFC ORIENTATION" for that mechanism of defining FRONT and BACK of triangles. Of course, if you want the definition to be opposite, i.e., run through the points in CLOCKWISE order to see the front, then your definition will be called "CLOCKWISE BFC ORIENTATION". Every LDRAW file can choose which definition of FRONT and BACK it wants to use. It does so by writing a statement into its header:

0 BFC CERTIFY CCW

tells the consumer of this file that its contained triangles and quads follow the "COUNTER CLOCKWISE" definition for "front" and "back". Opposite to that, writing

0 BFC CERTIFY CW

into the header tells the consumer of this file that its contained triangles and quads follow the "CLOCKWISE" definition for "front" and "back".

Ordering the points of a triangle or quad this way is called the "winding" of a triangle or quad.

Why is "Front" and "Back" Information of Surfaces Useful for Renderers?

If a renderer knows which side of a face is "front" and which is "back", and if a 3D geometric object made of such faces is looked at in 3D space, then a renderer can profit from that: it can know that those faces, of which only the rear can be seen, can be left out from rendering, if desired by the user. You can see an example image showing that mechanism in action in the Wikipedia: back-face culling. Leaving away these faces from the render can speed it up significantly.

"BFCing" an LDRAW File

"BFCing" an LDRAW file means to do 2 things with it:

  • Adding a 0 BFC CERTIFY CCW or 0 BFC CERTIFY CW statement to its header, and thereby stating that all its faces are (intended to be) properly oriented.
  • Checking that all faces are oriented in the file in the way that all part "outside" is formed by "front" faces and all "inside" is formed by "back" faces only.

Achieving this requires that a part author corrects the sequence of points of the surfaces inside the file.

So, making an LDRAW file properly oriented will usually be an iterative process of

  • looking at a rendering of the file and check that no "back" sides can be seen
  • if some "back" sides can be seen, change their orientation
  • repeat this until everything is properly oriented.

Using LDView

If done manually, this of course needs tooling support for a human. A good means is using the program LDView. It offers a nice mechanism of coloring surfaces, depending on their orientation. To use it, customize its toolbar so that that toolbar has the "BFC" button. When that button is enabled, the colors shown in a rendering of a part will be assigned as follows:

  • the FRONT sides of surfaces will be colored GREEN
  • the BACK sides of surfaces will be colored RED
  • if that orientation cannot be computed (either because a file does not properly state that it has oriented surfaces, or if the surface itself is de-generated), then that surface will be shown in BLUE

Here is an image of the famous 2x4 brick, rendered in LDView without BFC coloring applied:

LDView - Rendering without BFC Coloring.png

When turning on BFC coloring, a properly BFCed part will be shown like this:

LDView - Properly BFCed.png

Here is an example, where 1 surface intentionally has been wrongly oriented, for illustration purposes:

LDView - BFC Error.png

0 BFC INVERTNEXT

By writing the line

0 BFC INVERTNEXT

into a file, a part author states that the orientation of the next line shall be flipped, i.e., its "front" and "back" sides shall be swapped. This is the most trivial way to "flip" a surface. Of course, this "costs" writing 2 lines, so the preferred way instead is to reverse the order of corner points of a surface instead. Doing that by hand is quite tedious and error-prone, therefore using a program to do that is easier:

LDraw Design Pad

LDraw Design Pad is a text editor for editing LDRAW files. It offers the usual text editor features (edit, cut, copy and paste, etc.pp). Additionally, it offers the "reverse the sequence of corner points of a triangle or quad" button, which has been added exactly for the process of orienting the surfaces of a file properly.

LDraw Design Pad - Change Winding Button.png

LD Part Editor

LD Part Editor is a 3D + Text source editor for editing LDraw part files. Among its many possibilities it allows to highlight back faces and to change their orientation. I generally choose "Red backface" coloring (right click in 3D view window, then View Actions -> Red Backfaces). Less flashy than red/green mode, and it lets you properly see patterns on top surface. To change a face orientation, select it and click the "Swap BFC Winding" button or use the "J" keyboard shortcut.

Bfdldpe1.JPG

You can also change orientation of selected lines in the text view using the same button, as shown below.

Bfdldpe2.JPG

WINDZ

Some attempts have been made to automate the manual surface orientation process described above. One of the results is the program WINDZ. It does repeated renders of a file and checks if a "back side" is visible. If yes, it inverts that surface and tries again. After some attempts it gives up. In many cases, WINDZ produces quite useful results already, and only minor manual corrections are necessary after that.

History

In its early days, LDRAW parts were developed without caring for BFC. Later, the BFC mechanism was added, to allow a speedup of renderers. That required to add the syntax elements described above to the LDRAW file syntax. The syntax elements are:

  • the prefix "0 BFC" for all commands that deal with BFC.
  • after that, the individual command follows. The set of possible commands are
    • 0 BFC CERTIFY - this command states that the file intends to only have properly oriented faces
    • 0 BFC CCW - this command states that from here on all surfaces are oriented following the COUNTER CLOCKWISE definition described above
    • 0 BFC CW - this command states that from here on all surfaces are oriented following the CLOCKWISE definition described above
    • 0 BFC INVERTNEXT - this command states that the orientation of the 1 next surface shall be vice-versa, i.e., front shall be back, and back shall be front

Best Practices

To keep things simple and efficient, LDRAW has adopted some best practices for its parts:

  • there must be only 1 BFC CERTIFY statement in the file, and it has to be at the beginning of the file (in its header)
  • in the same line, the CCW or CW orientation must be defined. This boils down to the simple rule that each properly BFCed file must either have the line
0 BFC CERTIFY CCW

or

0 BFC CERTIFY CW

in its header. CCW is preferred.

  • Within the file, no switching between CCW and CW should occur.
  • Writing 0 BFC INVERTNEXT should be avoided where possible, and only changing the sequence of corner points of triangles and quads should be preferred.
  • Therefore, the only really useful purpose of the 0 BFC INVERTNEXT statement is to invert a primitive (for example, a torus segment). Note that 0 BFC INVERTNEXT should not be used to invert flat primitives (eg. discs). Instead, mirror it across flat direction.

Status of the Official Parts Library

Much effort has been put into making all official parts BFC compliant, i.e., having properly oriented surfaces. Somewhere in January or February 2018, we reached the goal of correcting all currently official files, and submitting their BFC-corrected version to the Parts Tracker. Although not all of them are already certified to be contained in the next official parts release, this still is a major milestone, because looking into all parts and "BFCing" them was tedious work. All of these corrected parts will be contained in the future official parts update, so that at some point of the near future, a release will be done inside which all official part files are BFC certified. The Parts Tracker currently has a special page which lists all files it knows which are not BFC compliant:

New Parts

New parts uploaded to the Parts Tracker should always strive to be BFC compliant from the beginning. We do not want to re-start a phase of having to re-visit part files for their "BFC-fication". New part authors should try to understand BFCing from the beginning.