Sunday 25 November 2012

Further Progress on CAM Module API

It's been over a month since the last post. We are making good progress on the CAM Module. Andrew Robinson has being putting his great coding skills to creating a very powerful API for creating Tool Path Plugins - considerably better than what I had already achieved. It's great to reflect on the different perspective on approaching a given problem. Our greatest difficulty is probably the time zone difference, when he is awake, I am a sleep. It's made communication interesting at times, especially the late nights.

With major rewriting of the API and being quite busy on my own project recently, I haven't been involved as much other than discussion.

New Github branch:

To collaborate better and remove old code, following a manual merge we had to also create a new Git-hub branch titled cam-py to push our work to.

Taking a step back to take big steps ahead!

From working together, it was clearly obvious that using Boost::Python was not the most elegant of solutions and having no experience with python it was not the most elegant method of approaching the loading and registering plugins.

Over the course of the past month, Andrew has been developing the python plugin loading and re factoring some of the factory methods lower down, so that Python plugins can be searched and loaded at run time. This essentially means you can rewrite and edit your scripts whilst FreeCAD is running. Potentially we could explore the idea of having a script window. What would be interesting in the long term is having an online plugin repository that allows individual developers / users to tweak the scripts and share these with everyone online.

Dynamic Loading of Library Plugins:

Most applications allow library plugins or extensions to be dynamically loaded at run time. Having compiled library plugins creates an interface to allow proprietary plugins to work with the FreeCAD cam module. It could be argued that we should promote openness but it gives freedom and flexibility for commercial developers to offer their solution using FreeCAD. 

Also we have decided that for the Cam Module, all c++ TPGs will be loaded dynamically like this. Since each plugin is loaded on demand, memory consumption should be reduced and loading times when switching to this work bench should be improved.

Building up GUI interface:

Andrew did some work on the GUI using a separate dock interface - which currently scans and loads python plugins into the application. Below is a screenshot demonstrating that Cam Module loading two python based plugins. 

The design of our API aims to have no discrete distinction when loading and using c++ and python TPG plugins inside the CAM Module. 

Next steps:

Work will continue on getting the API working and building the plugin infrastructure into the FreeCAD document structure so that we can allow geometry to be extracted and used by the plugins in their algorithms. Also how data is stored permanently needs to be implemented too.






Saturday 27 October 2012

A busy-ish week. Further work on CAM Plugins

The week's been a busy one with Group Project work at University - having way too many meetings, that haven't resulted in a great outcome.


Work on the CAM Module (no pretty pictures):


This post is in reference to recent commit history in the CAM developer branch


Nevertheless there are has been a few more opportunities to work on the CAM module.  The Cam Objects have been tweaked so that the Tool Path Generators are automatically updated when there is change to the Part Geometry and the Stock Geometry material. This is useful for obvious reasons so that the whole Cam Feature will automatically update itself and along with this the resultant GCode rather than having to manually calculate all the features again.

The next step was attempted to integrate a Cam Library - libarea-clipper into the source tree and make the python bindings available for other python modules within FreeCAD. This was only really good practice learning how to play with CMake configuration files, that's all, but the end result is that our TPG's can now use this library if they are c++ or python!

Work also began on working on the TPGFactory methods for essentially loading all the TPG's if they are c++ based or Python based.

C++ was pretty straight forward going where we can interact with the TPG and TPGFeature very easily.

Python requires making an extension using boost::python. This has its set of many difficulties and still has alot of work to get done but in practice it does work.

One stumbling point was that for TPGPython our c++ python extension to be loaded into Python, we have to put this in a seperate dynamic library. Frustratingly this took some time to realise and required numerous changes to the CMakeLists.txt file - the build configuration script we use.

Another painful learning experience was figuring out why the virtual method run()  was not being called. This virtual method is defined inside python and are later called. The first thing I forgot was define the callback - see here and I had implemented the run method in TPGPython which created a conflict. Finally atleast we have an interesting message when we call the run method()

I've also implemented the file search function that looks for .tpg files within a directory and is recursive too.

There's still a lot more work to do, but things are coming together fairly nicely. My apologies if this post hasn't made  much sense.

Sunday 21 October 2012

Help for creating C++ Modules in FreeCAD

Being slightly hungover from a crazy night out, I figured I might aswell try and doing something useful, so I am going to try and explain the structure for implementing a structure using c++ in FreeCAD.

It's useful to understand this to build a clear logical  structure rather than a mashup, which makes it more easy to document improving accessible for people to understand how the module fits together and get them developing! That's one of the reason's I'm not a big fan of using python solely in FreeCAD modules...

The App & GUI:

FreeCAD is essentially built around two core areas - the application code and the GUI which is essential for users to get something productive out of the program. 

Application:

The application provides the facility to perform operations, calculations, managethe document structure and its features. It's built around numerous libraries, the obvious one being OpenCascade which provides the modelling features. The application should be usable without a GUI so it behaves like a console application. 

FreeCAD comprehensivly uses python throughout to give greater power to users and ease development. It's very easy for the users to run commands in the python interpreter. Even still the application code can still execute python commands which are typically used for creating / editing features but quite essential for enabling the undo-redo system to work.

Any GUI related libraries cannot be used in the application module, however, we can still use some modules from QT as part of the application modules, such as:

  • QTCore
  • QTNetwork
  • QTXML

The Gui

The GUI is infact optional, and this can be ommited whilst compiling. This eventually give us greater flexibility in terms of the user interaction. For example we could in theory build a WebGL version of FreeCAD.

The GUI uses the Coin3D for managing the OpenGL Scenegraph based on the Open Inventor whilst we use Qt4 for providing the overall application user interface. These are linked together using SoQtViewer. 

Building a Structure:

I always recommend to look at the Sketcher Module which despite it's complexity is a classic example of how a c++ module should look.

It's best to seperate the module into two seperate folders atleast, the App and the GUI folder. This helps prevent cross contamination of GUI code into the application code. 

Below is simple diagram explaining how the structure fits together.



Each module will have it's own Features and potentially sub features too. Depending on the complexity of the feature, these features should only provide an interface (python) to another class which is intialised as a protected member and is callable. This keeps the document feature easier to work with and keeps the main functions are processes isolated together. Usually I create a seperate subfolder in the app directory to keep these classes together.

Each document feature declares a string to a specified viewprovider - defined in

const char* getViewProviderName() const 

This allows FreeCAD to load the viewprovider if there is a GUI interface. Each View Provider is assigned a pcObject which references the document feature that it is assigned to. other gui elements have to be implemented such as command.cpp, workbench and if needed the taskdialog and its taskboxes.

Document Objects / Features:

Each Module will have to define its own document feature, this is achieved by inheriting from App::DocumentObject.  There are many virtual class members that can be overriden. Each Feature has then several properties that can be used to store such as
  • Integers (App::PropertyInteger)
  • Floats (App::PropertyFloat)
  • Strings (App::PropertyString)
  • Lists
  • Links (App::PropertyLink)
  • SubLinks (App::PropertySubLink)  - a link to a feature and with a sub reference (e.g. a face, or edge on a part)
Including these makes life much simpler for the programmer; we don't have to worry about undo-redo mechanism and saving and restoring these into the document. We can also define our own properties but this introduces further complexities and should tried to be avoided.

We can link together other features using links and this introduces a dependency. When the sub feature is touched - its properties have changed, the parent feature will update itself accordingly. We can control this behaviour by re-implementing the following methods

  • void onBeforeChanged(const App::Property* /*prop*/)
  • void onAfterChanged(const App::Property* /*prop*/)
  • void onChanged(const App::Property* /*prop*/)
  • short mustExecute() const;
The main calculations or functions are perfomed in

App::DocumentObjectExecReturn *execute(void);

these are called when the recompute method is called either for the document feature or the whole document.

A document feature can also be implemented to take advantage of python. This requires defining an XML file and then implementing the generating functions in a myFeaturePyImp.cpp file. Generally an argument list is parsed and then if valid the correct c++ functions are called in the document feature. 

ViewProviders

ViewProviders provide the majority of the interface for a document feature. It manages the object's presentation and manipulation in the 3D view by allowing the developer to manipulate the Coin3D scenegraph. Also it defines how the feature is handled and presented in the Document Tree.

ViewProviders inherit from Gui/ViewProvider.h but can also inherit from other ViewProvider classes to obtain already defined behaviours. There aren't any members that need to be defined but it makes sense that you do.

GUI::Commands

These are basically commands that are registered in the GUI application that can be called by tool bar icons or the main menus. These can be programmed with a lot of logic during the prototyping phase, but it's not recommended that they are simple commands which will use the python interface.

 The things to remember:

  • Seperate your module into Application and GUI
  • Keep your Document Features as interfaces
  • Use App::Properties to save you time
  • Seperate processes and calculations into seperate classes
  • Keep Things Simple At First - get your module working and build up

Friday 19 October 2012

2000 Reads and Quick Guide to connecting Boost Signals

Well to say I only started this blog in summer, I'm pretty impressed to reach 2000 reads. Atleast someone must find my writing useful. Further work continues on refining the structure of the CAM module. Things are going reasonably well and each piece of the jigsaw is coming together.

I also stumbled on a little GEM on the forums after I was having problems creating the Document Objects that have children, for example like this hierarchy below...



If we delete ToolPaths using the GUI, ideally we want the children (TPGFeature) to be delete accordingly. Inheriting from a App::DocumentObject we do not get such a luxury.

Solution - Using Boost::Signals:

We need to set up an signal/slot mechanism using the Boost Libraries to observe when a document object is deleted.These are pretty simple to use and remove the need for having to use QT and it's signal/slot mechanism that requires inheriting from QObject and run through the MOC preprocessor. This is fine in context of the GUI interface, but isn't necessary in the rest of the application.

Boost signals are pretty straightforward to use:

In the class header file we need to include these. Essentially the typedef is just a typing shortcut to make the syntax less cumbersome to write.
#include <boost/signals.hpp>
typedef boost::signals::connection Connection;
In the class declaration we need a Connection member delObjConnection and this slot function that will be called when a signal is intercepted. In our case, when the signalDeletedObject is made within our slot function onDelete we need to have a App::DocumentObject as parameter. This slot function has to be public.
public:
    ///SLOTS
    void onDelete(const App::DocumentObject &docObj);
protected:
    ///Connections
    Connection delObjConnection;
In the class definition, we now need to set up our connection and also implement our slot. The function onSettingDocument overrides the implementation in App::DocumentObject. This is called just after the CamFeature object has been constructed and has a document assigned to it. (This was only recently added in the GIT master)

CamFeature::~CamFeature()
{
    delObjConnection.disconnect();
}

void CamFeature::onSettingDocument()
{
    //Create a signal to observe slot if this item is deleted
    delObjConnection = getDocument()->signalDeletedObject.connect(boost::bind(&Cam::CamFeature::onDelete, this, _1));
}

That's pretty much it. Now we can delete child objects in the onDelete slot we have made!

Wednesday 17 October 2012

Cam Module - Work over the Weekend

Git Repo:

I have created a GIT Repo on github that the other guys are going to push back their changes to, so look here if you're interested in seeing our progress.

Weekend Work:

I spent the last weekend laying the ground work structure for the FreeCAD Cam Module - inadvertently helped by my student house mates being away, making it calm around here. Essentially the hardest or laborious task was creating the source structure. There are several classes which require both the declaration and definition just to work. This leads to a file tree in the module like so:


And there's more GUI stuff too!

This was created based on the design document we created over last week outlining a proposal for how all this stuff could fit together.



The Dependency Graph:

FreeCAD has a fairly intelligent system of managing updates through the document. Each document object can be referenced by a series of links which behave as dependency. When a Document Object changes or it's property. When this happens the property or Document Object is 'touched' and this indicates it should be recompute the hierarchy tree.



Any dependencies that reference this object will automatically be requested to recompute and update themselves. This is what drives parametric design but being transparent to the developer.

The first attempt at fitting these classes together wasn't entirely successful and in its process also made the discovery of some good fixes in the base FreeCAD application. The end result for the dependency chart (below) for the structure seemed logical but introduced several difficulties.


Logically the structure makes sense in terms of the object hierarchy. However, for the program it doesn't. When the StockGeometry, or CamPartList features update, the tool paths will not automatically update. It took me two hours to figure that one out and it didn't look pretty. Boo hoo.

I had two beers and a night off to think about this on Sunday. It became apparent that the CamFeature was simply a top level container that would provide a general interface for accessing and managing the other features - it didn't control the actual CAM process.

Instead I created an object hierarchy like so. Essentially GCodeFeature is the result from the combined results of the TPG. However we get the all the glorious updating mechanism with this.


The ToolPaths manages the Input and controls the process of updating the TPGFeatures eventually more intelligently.

The TPGFeatures are quite dumb. They behave like blackboxes and are given an input, do their thing and spit back a result. The nice thing is thing about this it will allow new TPG's to be more quickly developed since the developers don't have to set up the document feature, but only have to provide the input and in return can get the GCode back.

Sunday 14 October 2012

CAM Module

FreeCAD CAM Module.  Take 2:

After a fair bit of discussion through the Google Docs, Blog Entries, Forum Posts and ofcourse some IRC chatting Ideas we have pushed again and started the CAM 2 Module. Perhaps it's incorrect to say CAM2 but we are definitely putting the new source files in a new folder since we are essentially starting from scratch. We have even been blessed with a new subheading on the FreeCAD forums.

Objectives for this Module:

Essentially we aim to integrate the whole CAM workflow into FreeCAD.  The tool algorithms are developed  already in many libraries and are already useful but there is no practical integration within FreeCAD.


Secondary Objective : To cut out Sliptonic's spider!

The rough workings of CAM from a newbie:

The module will take your 3D Part within FreeCAD as the primary input. We provide a set process this with tooling algorithms which generates machine instructions (tool paths) known as GCODE. These are post-processed manually by the user and can be visualised within FreeCAD to check for any problems. We are basing a lot of the design on the work already achieved by HeeksCNC.

CAM in this Module will be a subtractive process -we remove material from a piece of Stock - such as sheet of steel by a series of operations. Each operation will be generated by a TPG - a Tool Path Generator. These are plugins which can be written in c++, python perhaps other languages and use their own algorithms to generate paths for the CAM Machine to remove material. These TPGs aim to be flexible, so we can call a  process to proprietary application allow this to do the hard work and then import it back into FreeCAD, but this process being entirely transparent. 

How I fit into this:

The strangest experience with this side project is that I have very little practical knowledge and experience working with CAM so I am very reliant on the wisdom of our CAM experts who have set up their requirements and how the perceive it working within FreeCAD. This is what makes it interesting in respect but also a difficult task. It is good practice working in an environment like this because I still yet to find a job that involves team work at such level haha.

My role in this project is to try and build up the basic FreeCAD infrastructure and then this will allow the other developers such as awallin, arobinson, dfalck to work on this independently, integrating the tools in.

Additionally work to build an awesome GUI interface into this ofcourse!

Saturday 6 October 2012

Back to University. Back to FreeCAD. Updates

After my intermission of going on holiday in Europe (if you could call it that) , I am now back at University and have some free time to work on FreeCAD.

Coding Improvements to the Render Module:

The past few days I've tidied up the Render Module and improve the QML code to improve the quality of the UI presentation. In addition I have now implemented the saving and restoration of material properties, so this means for example you can save the 'colour' within the Matte material.

During mid-September inside the Render Module, I tidied up some QT and Coin3D GUI dependencies that existed in the core application functionality. These were trivial changes and other small coding improvements were made to the Render Module.

Building on Windows:

To give the Render Module a greater spectrum of Testers, we would like to get the Render Module compile on Windows. Work was done to implement class definitions that were missing.

There was a brief discussion on building using QT 4.5/ QT 4.6, which the current Windows Libpack includes. Unfortunately this doesn't include QML or/ QtDeclarative Modules, therefore it isn't possible to build the render module on Windows yet. In practice this means that the Render Module will not be available till the 0.14 release, when we can guarantee that most Linux distributions will include this. However, this will give another 6 months of testing to ensure that this module contains more features and improve the quality through testing.

GIT Housekeeping:

Having been working solely on the Render Module over the past three months, in my own ignorance, I have refrained from keeping an updated revision of the FreeCAD source. I've now forked and cloned from the FreeCAD source mirror on github and have set up a new repository and merged the Render Module into a new branch:

This somewhat both complicates and simplifies keeping upto date with the FreeCAD repository and there is always the added difficulty of learning something new!

CAM Module:

I am looking into helping start an initiative to implement CAM functionality into FreeCAD with guidance from Daniel Falck and Brad Collette. Currently trying to work out how this system will work and draw up a structure for this. I will report back on this in short time.

Saturday 15 September 2012

Building a Computer and upgrading to OpenSUSE 12.2

Slightly offtopic.

Despite returning home over the past two weeks, my computer has been ill. It suffered from complete system crashes, which became apparent when making a video and compiling FreeCAD. I thought this was a memory problem because it was happening in Linux and Windows.

I decided that for 5 years, my computer has served me well through College and three years of University on heavy CAD and FE simulations and it was time for an upgrade.

I've been an Intel user all my life. Looking at the prices of i3-i5 processors, I didn't think they were worth it. I got marginal performance over my quadcore Q6600 for £100 spent. I decided instead to brave a new world of AMD. I purchased a 6 Core FX 6100 with 12mb cache, 8GB DDR 3 Memory and a Motherboard for £175. I consider that a bargain.

Setup was straightforward and I was upgraded within an hour. Windows worked fine after updating and so was OpenSUSE 12.1. I decided to do a live upgrade to 12.2 following these instructions This took a good two hours to find for some reason, but the process went very smoothly unlike terrible experiences I had with Ubuntu derivatives in the past.

Compiling FreeCAD:

Whilst upgrading, external repositories had to be removed. To my suprise FreeCAD nearly compiled straightaway. All the FreeCAD dependencies are now included in the default repo: I just had to include swig, python-qt4


# install needed packages for development
sudo zypper install gcc cmake OpenCASCADE-devel libXerces-c-devel \
python-devel libqt4-devel python-qt4 Coin-devel SoQt-devel boost-devel \
libode-devel libQtWebKit-devel libeigen3-devel gcc-fortran git swig


OpenSUSE 12.2 automatically installed python3-devel but this needs to be removed to successfully compile FreeCAD. We are hoping that we will update FreeCAD to use this with the successive 0.14 release.

FreeCAD now compiles blindingly fast: under ten minutes for a full compile and my system stays responsive in the background.

What will be interestesting next is to profile FreeCAD on so many cores. 

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!

We have working render templates!


After a few days of working with a day off finally getting out of the small village I live in, we have a render template system that is working.

Here is the Schenkel part - does anybody know what this is? Attached with a Matte material with an orange colour:

Before:




After the render:




Now lets turn it into glass!



Here I am using the classic theme created by Yorilk. It's a basic box scene with two area lights. It's not bad to say it takes about 30 seconds to set up. 

Sunday 12 August 2012

What is QML?


I'm sparing some time to explain QML: Qt Meta Language - officially apart of  Qt Quick and draw in some of my early experiences learning and using it over the past week.

Quick Introduction:

Qt Quick is a set of technologies provided by QT for developing powerful, interactive user interfaces and building programs by using a declarative programming language. The video above is a an example of some programs created using Qt Quick 2 in the upcoming release of QT 5.

Qt Quick allows dynamic interfaces to be created using animations with tweening and all the other fancy bells and whistles, whilst retaining high performance especially by being multi-threaded. Because it's interpreted at runtime, you can modify the QML file and reload it without having to re-compile the application. I even think it's possible to download and load QML from an internet source.

An example of a game produced entirely in QML. A video showcases QML significantly better!



Without being a user interface expert, I would suggest a powerful user interface is one improves the user's workflow and experience when using a program. It's there to also present information in a meaningful way and manipulate it in the most straightforward manner - the method that's is usually the most time saving. This is all in context of the user.

It's my belief that the idea for Qt Quick was conjectured before Trolltech was acquired by Nokia and was intended to compliment and build upon the introducing of Qt Script bindings and the QGraphicsScene introduced in early versions of QT 4.

Qt Quick will not solve everything! There will be appropriate times where interfaces will need to use standard desktop widgets.

A bit about the language:

A declarative language allows the programmer to express a structured program without having to necessarily care about the program flow. Essentially the programmer has to only care about declaring objects and letting the compiler/interpreter figure out the intended behaviour. I think it's difficult to describe, but to draw parallels, the most commonly used declarative language available today are HTML / CSS.

Built upon Javascript and JSON

Qt Quick is built upon a JSON/Javascript structure which due to its nature is very flexible dynamic language to begin with - due to lambda functions and not being strongly typed. Nevertheless javascript or it's more avoided name 'Ecmascript' has many quirks and problems; for interest see videos from Douglas Crockford - the creator of JSON. Despite many cases against for using this language in application development outside web development, it's starting to become very popular due to adavances in using JIT Interpreters.

Playing with Qt Quick using QT Creator

With the latest release of QT Creator, you don't even have to program anything. You can actually use their built in Design editor to build up the QML interface graphically. Otherwise you can code it normally. Unfortunately there is no parsing in KDevelop for QML, so you will have to resort to using QT Creator for code hints. It's very easy to set up a test application: just click new project and hit Qt Quick UI.


You'll be present with a screen with main.qml:


Make a few changes and you can then use build->run to test it out. If you're interested, you can start learning here, or wait for a few guides I may create later.

My Experiences with QML:

I have spent over a week learning and using it to build up the Render Module UI in FreeCAD. It's been relatively very good. It's very quick to learn and I was very surprised how easy it is too build an interface very quick and add some nice transition animations without having to spare too much thought. 

The convenience of JavaScript makes a lot of c++ code redundant for implementing GUI's because we can begin to use a model-view structure. This makes both programming and maintenance far easier and allows more interested program users get involved with the development of the program.

It's also giving me greater flexibility to build interfaces that are generated after the program has been run: more on this later...

Not everything is great:

The syntax can be slightly frustrating which isn't helped by the QT Creator IDE hinting. One of the big issues I am finding is the scope of functions - in javascript, when a function is called, this is binded so you have access to the previous scope. 

Nokia has pushed too much into making this into the mobile space. For example, to access mouse wheel events you have to create your own object and plug this into QML. Additionally there should be at least a repository or references for building common desktop widgets such as combo boxes just to save time and have a more unified interface. 

It's also a point that there will be inconsistency with the overall application user interface. This may not be a problem - it will later be possible to create native looking widgets:



My other complaints are that there aren't enough examples and the documentation is lacking in places which when you get stuck on something it can become slightly time consuming. 

Otherwise I would give Qt Quick a thumbs up and is heading in the right direction!

Friday 10 August 2012

Debugging C++ using KDevelop

This is leading on from another post. Without being able to debug a program, it's very difficult to get anywhere or learn mostly from stupid mistakes and is a quintessential for making progress. Thankfully having a good IDE makes all the difference and I present to you how I use KDevelop to debug FreeCAD during development.

Debugging with KDevelop:

First ensure that you are compiling with debug symbols / information and set up KDevelop so that you can compile and launch FreeCAD successfully. Please see my previous post for information.

Open up KDevelop and then you can hit Debug.


The KDevelop workspace will now change to Debug Mode. It is more convenient to present tool panels that are more relevant to debugging than programming. The only frustration is that the Editor will not remember which file you have currently opened from the normal mode.

You can customise which tool panels are available by right clicking and selecting like so:



Useful tool panels for debugging are:

  • Variables
  • Breakpoints
  • Frame Stack


Creating and using breakpoints using KDevelop:

FreeCAD will load, but can take slightly longer since the GDB debugger is launched and use to monitor the FreeCAD executable. Breakpoints allow you to control the flow of program at any point in time where you can:

  • Pause on a line / statement (A statement is usually terminated by a semicolon, e.g. int i = 0;)
  • Run each statement one by one
  • Continue to the next breakpoint
By setting breakpoints, it allows the programmer to control to examine segments of code and check the behaviour of the program or complex algorithms. 

Setting a Break Point:

In the code editor window, look for an area of code that you want to examine and isolate a line where you want to pause the execution of the program. In KDevelop, click on the furthest area adjacent to the line to create a breakpoint.  KDevelop indicates when a break point is set by displaying a ladybird / ladybug.


Sometimes it is useful to set the editor to visualise the line numbers which can be done by enabling the option at Editor->View->Show Line Numbers



Now, run the program normally and attempt to 'trigger' the break point by performing an action that will cause the segment of code you want to be executed - sometimes that's not always straightforward! When a break point is hit, KDevelop will highlight this.


We have paused the execution of the program. We can control the flow by using the debug toolbar at the top.


Importantly, Step Over will run to the next statement on line 43 - this would be std::string path = hGrp...

Continue will run till it reaches the next Break Point, this could be set in the same segment of code, or in another completely different area of the program. So in the example below clicking continue would run all the program till it reaches line 48 - args.push_back(QString...


The other two I rarely use, but they will enter a function or exit a function, but often I found going directly into these function sources and setting my own break points are easier. All break points are shown in the Break Points tool view. These can be toggle on or off and can be deleted. 



*Useful hints:


  • Remove all previous break points if you have recompiled FreeCAD with modifications to the code, or even just launching the program. I find it much quicker to launch FreeCAD in debug mode by doing this.
  • The more editors tabs you have open, it appears to take longer to launch and consumes more memory.

Making use of Break Points:

When we stop the flow of the program, we can examine the current state of the 'stack'. KDevelop makes this exceptionally easy. We can find the current values of variables or properties of classes/objects. This can be done by highlighting over a variable or object using your cursor:


Alternatively you may use the Variables Tool View to examine all the variables accessible within the 'current scope' or on the stack. It presents a hierarchical tree and can present meaningful data for known variables types and classes within the project tree:


All it takes now is some logic and wit to figure out what is causing the problem. Sometimes it can be blindingly obvious and for other times it can take hours :( The more practice you get the easier it seems to become.


The Frame Stack:

This is most useful when you have a sudden crash.

 Conventionally a stack can be imagine like a stack of  dirty plates at a restaurant. When you enter a new program scope (e.g. run a body of a function) you add on a dirty plate (so the dirty food represents variables). Conversely, exiting a program scope you clean the plate and take off the stack of dirt dishes. I tend to imagine it like an onion, you must peel a layer to access the inner layer. 

You can view the current state of the stack using the Frame Stack Tool View, when a program crashes GDB will display the state of the frame stack to help identify where the crash occurred. This will be at Depth 0, but logically you may have to look higher up to understand why. Usually the current state of the stack variables can also be accessed using the Variables tool view. (*precaution GDB will crash if you attempt to access a null pointer)

Below the current program is on line 49 within the LuxRenderProcess::initialiseSettings method. This method was called in Renderer.cpp on line 363. It is simple as that. 



Hopefully this guide will help you get debugging and make learning how to program c++ within FreeCAD that much easier!

Thursday 9 August 2012

Render Module Updates

I have been working the past couple of days tidying things up by implementing a new Render Feature into the document tree. This further abstracts data between Renderers, so technically you make simultaneous renders providing your machine is powerful enough, assign different materials to prototype different visualisations or have different views or possible even using different Render Backends... I'm not sure about the last one, atleast regarding material selection.

U-Tube Video:

I decided it was an appropriate time to showcase some of the work that I've been doing for the past two weeks with some notes to accompany it for those interested. It hopefully shows the current state of the Render Module development for those who haven't yet tried the rendering branch. Apologies for no audio commentary, but I don't have a microphone. 


Current State:

We now have a basic UI which gives the ability to start and stop render previews and set basic options such as the output size. This also can be done through python but adds little benefit... 

Currently per RenderFeature, only one Render Process can be used, which makes sense. Buttons are disabled accordingly. 

The annoying thing with QML is that basic components such as ComboBoxes and Number Inputs don't exits - you have to create them yourselves. It's actually not bad as it sounds and slowly I'm building up a slick interface.


The Render Output preview window now works correctly. It can be scaled using the mouse wheel button and dragged around. Sadly I couldn't figure out how to zoom to cursor.

Currently it just uses a polling mechanism, but I later plan to use QFileWatcher to more intelligently check when a new output is created so we don't get LibPNG checks.



Drag and Drop Material Goodness:


This feature I'm really happy with after wrestling with the QT event system for an afternoon, the Drag & Drop material interface now works. In the screenshot above the icons are missing. 

Currently it only intends to assign materials per feature, but later this behaviour can be changed. QML however is not playing very nicely with the current task view. So I may even have to make my own sub class just so that it's contents are scaled correctly, but it would mean slight inconsistency not having the OK | CANCEL buttons unless implemented within the QML File.

So that's it for now. Still more work to do on this!