Showing posts with label Lux Render. Show all posts
Showing posts with label Lux Render. Show all posts

Wednesday, 22 August 2012

Render Module Updates:

A lot has happened since my most recent post. It's time to share more work on the Render Module. So I am grabbing some tea and getting ready to share it with you all:

Improvements to Render Interface

Toolbar:

You don't have to edit a Render Feature to preview it. Simply ensure that the settings are set up to how you desire. Then click the preview buttons within the toolbar.

Buttons (From Left):
1) Add Render Feature
2) Render Preview Window
3) Render Preview (uses stored settings in Render Feature)
4) Add materials when editing a Render Feature


Render Task View:

Further updates to improve the completeness of the Render Task View. Render Presets and Templates are correctly set from the combo boxes. 


Material Selection:

All render materials that have been assigned within the Render Feature are now displayed in a list view. These can be selected and deleted, or if double clicked , the material properties can be edited. 


View shows material Labels:

When editing a Render Feature, all materials that are assigned to any objects has some Material Labels displayed. This is very basic admittedly, but for now will suffice to help keep track of what materials are assigned within your scene.

Render Templates:

The inclusion of the Render Templates was the last remaining major feature that was to be implemented. This has further been improved so that they are positioned in a more optimal place respective to the scene geometry and the camera. This is not perfect but is certainly ideal in most cases.

We can more easily now zoom really far out like this.


Or zoom in really close:


The Render Template will take into consideration the bounding box of the visible parts in the scene and the camera itself. It will move the template to the middle of the scene bounding box and then scale it according to  furthest point away from the bounding box center.

Material Selection & Editing:

I have finished of the material selection interface, so you can set and edit parameters. Now this has undo-redo system built in making things easier. On a similar note materials and cameras can be saved. (Material properties aren't saved yet).

The colour chooser and number inputs now correctly retrieve and store values. It needs refinement but most importantly is function. Ideally it needs a button to allow more sophisticated selection from a QtColorChooser Dialog. Other ideas are having predefined material presets, which become more important on more complex materials such as plastics and glasses.

The above screenshots show that material properties are dynamic. Just define the properties in the XML file and the GUI figures out how to use them and store them. Here's the XML sample for the right:



Well that's most of the major changes! I need help with testing and making materials and templates for people to use.

TODO List:

  1. Ability to Save Material Properties
  2. Make adjustments to the user inteface
  3. Add more render materials and scenes
  4. Python bindings
  5.  ???




Wednesday, 15 August 2012

Creating FreeCAD Lux Render Template

This is for the upcoming Render Module. Despite my very limited experience with rendering and modelling it appears that to get that 'wow' factor it will take a lot of scenes. Most people have better things to do so that is where templates come into play.

This guide will hopefully show how it will be possible to specify your own templates (for lux render):

Beginning with Blender & Lux Render:

The easiest way to create a template is to start with blender. A useful build and instruction guide for compiling Lux Render and using this in  Blender has been provided by Yorik on his blog

I don't have any clue how to use Blender, so you will have to figure that for yourselves. Nevertheless the important that you must have the scene normalised to a unit length. Ideally you have a cube with side lengths as one and build up a scene around this.
This is important because the scene will be scaled to the bounding box of the scene. I cannot guarantee this will work in all situations but it should give satisfactory results. Within blender you will need to export the scene to a  Lux Render Scene File Format with an extension .lxs 

Yorik created three example scenes that I am going to show you how to import as a Render Template in FreeCAD, these I have made available using google docs




Importing templates into FreeCAD:

For the scene template, we only need to find lights, geometry and materials information.

Materials are most likely to be used on the geometry within the scene. Using a templates like this means we can texture surfaces, which isn't going to appear within FreeCAD in the near future.

In this example open up luxscene-classic.lxs

Essentially we need everything from World Begin to World End. So extract all of this and you should be left with http://pastebin.com/qe3m0qXu 

One thing we need to change:

I discovered the long way that there is a problem with the way Blender exports the scene information to Lux Render. Unfortunately, you will need to go through the file and look for lines like these:


Transform [-0.083770856261253 0.000000133886644 -0.996485054492950 0.000000000000000 -0.000000133886729 1.000000000000000 0.000000145614280 0.000000000000000 0.996485054492950 0.000000145614365 -0.083770856261253 0.000000000000000 -0.465571254491806 -0.011301971040666 0.364225387573242 1.000000000000000]


These are transformation Matrices. These need to be removed and replaced with seperate Translation and Rotation properties for each object like so:

Tanslate x y z
Rotate angle x y z


With the rotation, you specify an angle about a given axis, so in the case of blender this may have to be done three times, in the x,y,z directions.

For example in the classic scene:

Select the Plane.006 object and look the object properties



So you would replace the Transform line with this: 
Tanslate 0.459 -0.01 0.6
Rotate 253.4 0 1 0



Place this into a file such as luxsceneClassic.lxs

Then inside the FreeCAD build folder navigate to data/Mod/Raytracing/Templates





Create a folder in Templates/Lux to hold your template such as Templates/Lux/Classic. Then copy the file luxSceneClassic.lxs you previously created inside here.

Within the same folder create an xml file and copy into this file the following excerpt:

<?xml version="1.0" encoding="iso-8859-1" ?>
<!--
 FreeCAD Scene Template for LUX Render, see http://free-cad.sourceforge.net for more information...
-->
<Document SchemaVersion="1">
  <Templates render="lux">
    <Template id="lux_classic" source="external">
      <label>Lux Classic Scene</label>
      <description> Classical Elegance</description>
      <provides>classic</provides>
      <filename>luxSceneClassic.lxs</filename>
    </Template>
  </Templates>
</Document>

For reference you only have to change the following:
  • id="lux_classic" : this attribute must be a unique identifier for the template
  • <label> Label for the scene template </label> : a graphical name for the scene
  • <description>Description for the scene template</description> : a descriptive identifier
  • <filename>luxSceneClassic.lxs</filename> the file name that contains the scene information
You should have a file structure like this:


I am not sure when you compile and build FreeCAD each time if this template folder will be deleted. Most likely not. Later, I will make a preference option so you can use your own folder. 

Using the Template:

Launch FreeCAD and switch to the Raytracing Workbench:

Create a new Render Feature.


A task view will appear. FreeCAD will automatically find your template. You can now select the template that is used in your scene. If nothing appears when you render, it is likely that the Lux Render Scene File Format has incorrect syntax...






Now position the camera where you want and hit Preview Window. Currently there might be times where the render is just a black screen - so to quickly solve this just play around with the camera a bit. 

Hopefully this make sense, feel free to post questions on here if you're stuck!

Friday, 3 August 2012

Finding the bottleneck using KCachegrind


I spent the afternoon trying to find a bottle neck within the Scene File Generation for the Render Module. It's not immediately obvious, what was causing the slowdown, which with complicated geometry was making me wait a precious 5 extra seconds. I wanted to write this because if couldn't quickly find on google how to use it to refresh my memory.

Here's a classic case of how Valgrind & KCachegrind came to help. These are virtual machines that profile your code and only need debug information to be compiled. It is both very useful for developers and also importantly testers to find memory leaks, segfaults, 100% cpu loading caused by infinite loops and so forth.

First download both Valgrind and the KDE Graphical Frontend KCachegrind.

Ensure the program your using has debug information and you're not using any compiler optimisation flags (-O3)

Now you can run the Valgrind profiler from terminal in the same directory as the program executable: issueing a command like this.


valgrind --tool=callgrind -v programName

The program will run, but it will be around 20-50x slower than normal during profiling.

-----
For developers if you know the program area that is creating problems, you can dump the output before and after a class method/function e.g.

valgrind --tool=callgrind -v --dump-before=Renderer::generateScene FreeCAD

Ideally the function should be called two times. This will produce 3  seperate files,
  1. Output before call
  2. Before second call
  3. Remaining program till termination
This can make it easier later to diagnose the problem using KCachegrind
-----
Using KCachegrind

Start KCachegrind and then open the log file generated from Valgrind. My first intuition was to look at the Renderer::generateScene where I knew FreeCAD was being slow.

Clicking on this in the left window, will update the right window area showing the call tree.

Scrolling down we can find the culprit (GeomAPI_ProjectPointOnSurf) that is causing the slow down:



This can be seen verified using the source browser:


Looking at the source code and simply commenting this out, I find out that this exert is not actually required. With its removal, generating the scene file was happening near instantly!

I hope this short guide may help some developers and testers!

Starting a Render Process

The scene file format from last time is generated into a QTextStream and then is saved using a QTemporaryFile ,which stores the scene file to a temporary directory with a unique name which is then accessed and shared later. Currently when generating the scene for more complex parts (e.g. curved surfaces with high tessellation) there is a noticeable delay. I will need to investigate whether this is due to storing textual data or the algorithms for generating the mesh information. Later it may be a nice experiment to try and multi-thread this.

The next steps really were to build up the Render infrastructure and allow the Render Process to be spawned within FreeCAD. With the help of QT and it's QProcess it's pretty straight forward. Just pass the executable path and a string list of arguments and run its start method. To give more flexibility and add different modes subclassing this seemed a good option. The nice thing about spawning a QProcess is that it runs in the background. Apparently launching new processes consumes more memory, but overall arguably is the simplest method of IPC: we don't need to link or include render sources and we can let the user  specify the executable path.

Actually the Lux Render Plugin (Luxblender) utilises its Python API and also a C++ API is available. It would be interested to experiment in the future which method works best.


The only difficult with subclassing I found was the QT macros, which didn't seem to work straight away. By subclassing, more events can be handled directly such as errors. The Render Process has some basic methods to control the process - BTW: pause will be dependant on the renderer executable. For example Luxconsole can be paused by initialising another process but with some extra command (see here)

Soon enough I got a process working. Without a GUI front end it was pretty useless though. In practicality it works well and I didn't realise but the external render process also stops when the host application finishes.

Thursday, 2 August 2012

Render Module: It's Alive!


I think the above is how I felt when it was working. Thankfully the night I got it working, I was treat to some BBQ duck which went down a treat along with the excitement of this.

Generating the Scenefile format

I'd thought I'd share a bit on Lux Render Scene file format: Scene File Format 1.0 This is based on RenderMan's scene file format (from the guys who make Toy Story!) . The structure of the scene descriptions is very similar to Povray which despite its age is very easy to read, the only difficulty is getting used to the syntax having being so familiar with c++ development. For example:

"float focaldistance" [1.5]
Nevertheless with a bit of practice it soon becomes second nature. Essentially the steps I took at producing the scene file description were to look at the output produced from the povray example included in FreeCAD and with the wiki page on Lux Render. By making this converter I could build up some of the infrastructure with the RenderPlugin and RenderClass. An output created from the RenderPlugin which is a pretty simple plane and cube is on pastebin

Using luxrender GUI I could then import and quickly find problems with the syntax. Sadly nothing works perfect the first time and I was getting outputs like the following:



It took a lot of perserverence to get correct. From here it took several tweaks to get it to work but mainly the following
  1. Triangular Mesh Indices were in the incorrect order (BRep_IncrementMesh) produces them in the incorrect order.
  2. Lot of formatting problems with the output
  3. Quite surprisingly but 'LookAt' descriptor must come before the Camera descriptor which is mentioned in the documentation!

Drum Roll Please... Finaly we got some output! 



Giving the program a few more tweaks and letting the material colour inherit from the Part Appearance colour property, eventually we get some nice looking eye candy! We can make things made in FreeCAD look sexy.


Just for proof, to show that it did originate from FreeCAD 


This is just beginning there's still more work to do and more graphical goodness to share!