Monday 12 May 2014

Drawing Updates

I've returned from an interesting cycling vacation in Europe and if I can call myself rested, it helped provide me with a bit more energy to gear me towards getting the Drawing Module finished.



With a steady stream of testing, I have been ironing out some long standing issues, some hidden bugs and adding a bit more functionality. Fuelled by beer and eagerness to get this module complete, there's been some steady progress over the last week - or if deemed worthy a coding 'sprint'.

There have been a substantial number of changes since last time, both visible and under the hood. I'll try my best to highlight the most important changes:

With anything this creates new bugs and also helps discover ones hidden away. I think the philosophy is starting to come true: you complete 90% of your project in 10% of the time and the remaining 90 % of time is spent debugging the remaining 10% .

New Features:

Drawing Icons

Drawing Icons are now used to represent objects in the drawing. Courtesy of Jim!




Dimensioning tool bar

You may now select specific dimensions for your drawing

Diameter constraints

I recently added a diameter constraint which has various positional arrangements depending where you position the dimension label. 

Centre mark option available for diameter and radius dimension




Drawing is updated dynamically when changing properties using property editor


Orthographic Task View Dialog:

Due to architectural changes,l the previous task dialog coded by Joe was difficult to incorporate with what I had done.  The difference now is the way views are now handled positioning and views are managed with a container object (Orthographic projections) - this allows you to set the scale for each individual view and eventually the projection type. 

These are automatically updated in real time. Along with this there are now three different scale types: 'Document' uses the page scale, 'Automatic' will attempt to calculate this automatically and also custom option. The latter two are available for all views.


Undo & Redo now possible

Before this was a notable problem where it was never guaranteed that you could undo and redo correctly. It appears to work very well under most situations - even deleting items. The only issue I have seen so far is when deleting a dimension this isn't correctly positioned when you try to redo operation. 

Improvements

  • Select 'anchor' view and now correctly drags the group
  • Drawing dimensions don't recalculate every time they are moved.
  • Dimensions correctly positioned when you save and restore the document. 
  • Reduction in number of document.recomputes - updates are automatically made. 
  • Vertical and horizontal dimension is checks edges are not zero
  • When you  create a page using the tool bar, the template is now loaded for the page (A4/A3) chosen
  • Tangent edges (e.g. cones, fillets) should now appear after disabling a check. Note: there is a limitation that these cannot be dimensioned

Reliability:

These are some recent changes this morning to try and prevent the random crashes/segfaults from occurring. As a result the bounding box also includes dimensions. I'm not sure if this is a good thing but I just need see if we still experience random crashes. This was a notable problem encountered in particular when you dragged a drawing view or more likely deleting a view. If I can get feedback on this over the course of time it'll help diagnose a better solution.

There  are more bugs out there some I'm aware of and some I'm not and to coin a nostalgia phrase we 'gotta catch em all'

Monday 31 March 2014

Testing the Drawing Module: Part 1

After initial round of testing, we discovered a re-occurring crash when you tried to open a newly created page. The result of last nights work this is now fixed. For those unfamiliar, in the FreeCAD_sf_master directory run 'git pull'.

If you have any comments after testing the drawing module, please also consult this forum topic

-------------------------------------------------------

I haven't managed to do much recently. Work has snowballed and I've been having to work on a binary file converter for an Additive Manufacturing Machine. The experience from that I can imagine may be quite useful for writing and parsing other file formats if we ever need to in FreeCAD. I never would have thought I would read binary numbers as an engineer...

It appears there is a demand for testing the Drawing Module. It's in the stage where I any testing would be quite helpful, mainly to get feedback on the user interface and push this into the master for testing. I am aware there are some deficiencies both in missing features and bugs, but I need some motivation to finish up the GUI to make it more user friendly. Input on this would be helpful. In particular GUI mocks - hand drawings on tissue paper are accepted!

Note: Windows testers would be helpful!

 The idea of this post is to give a brief overview building FreeCAD to test out the Drawing Module.
mkdir test && cd test

The run "git clone http:://repositoryaddress" like the below to clone my Github repository into your testing directory.
git clone https://github.com/mrlukeparry/FreeCAD_sf_master.git

It should look like below. Cloning FreeCAD shouldn't take too long (it's about a 70mb download).


Ensure you have the prerequisites for compiling and building FreeCAD - consult either the wiki
or if you are really ensure ask on the forums. 

You now need to checkout out the drawing branch 
cd FreeCAD_sf_master && git checkout origin/drawing

You should now be on the drawing branch in a detached state. 


Now we create a build directory outside of the source directory and then we configure using CMake

You now need to checkout out the drawing branch 
cd ../ && mkdir build && cd build

Now we build using CMake. The options that you pass may depend on your platform or distribution. If you have problems please consult the forums. Configure the build using debug options for testing:
cmake - DCMAKE_BUILD_TYPE=Debug ../FreeCAD_sf_master


Eventually you should be configured and ready to build. All you then have to do is run make. To build faster, the option 'j' is the number of make jobs to run in parallel - set this to CPU cores + 1
make -j 7
The build procedure can take between 10-30 minutes depending on your computer specification. An SSD helps considerably more so than memory. Once built you can easily test FreeCAD without having to make an installation. 

In the build directory you can simply run FreeCAD
./bin/FreeCAD

To use the Drawing Module change the workbench once you have a part.

Part 2 to follow! 

I think I will try and record a screen-cast for the next guide.

Saturday 15 March 2014

Drawing Updates

I am in the stage of trying to tidy everything up and get this baby into testing for you people to enjoy.

I noticed that the drawing performance in QGraphicsView was becoming very slow especially if you tried to zoom in. It wasn't really obvious why but through investigation I noticed that this was because of a QGraphicsItemRectangle that was being used to render the blank page background. This was even with caching enabled and redrawing seemed to persist which was the cause of the performance penalty observed.

The improvement I made was drawing the background page (a white rectangle) in the QGraphicsView drawBackground method. Instantaneously the performance was improved irrespective of zoom level. Everything comes at a price. The caveat was that we don't have a shadow for the background, but the main issue was very random segfaults. After hours of probing, it the cause was peculiar. An empty QGraphicsItemGroup was not updating its bounding box correctly. In short this got fixed with ample amounts of frustration. What is also nice is that much of the Drawing Canvas is cached so there should be little redraw slowing us down.

As a result the performance is significantly better and the user interaction on my computer is smooth.

I also was investigating the Task View created by Joe to see what can be used to create organised orthographic projections. Much of the functionality is built already in at a lower level except the automatic scaling. It's in all best interests to use code, but I am in the position where it might be easy to start with a simple interface that doesn't have all the logic embedded inside it. I'll post a topic on the forum for people's thoughts.

Through this investigation, now in a collection of Orthographic views it has an anchor view which is used to move the whole group. It already feels quite intuitive to use. This was misleadingly obvious to implement and I started off using Qt's signal and slot mechanism but this was causing a reciprocal effect, whereby movement was  exaggerated. After a few beers, I stumbled upon QGraphicsSceneMouseEvent::ignore() which allows a child items event to bubble through the child-parent hierarchy. To my surprise this work instantly and was also smooth.

Getting bored one evening, I wanted to experiment and see if we could have user-editable text fields for the SVG templates, rather than the cumbersome Property Editor. To my surprise it's quite straight forward using previous code and using the text elements in the SVG document to create QGraphicsTextTtem which can be used very easily.

Time for screenshot!


The picture above is a culmination of what's been done. The text block on the right were edited in the document. All that needs to be figured out is if people are happy with this and a mechanism for storing the data fields more intuitive than an array. 

Saturday 1 March 2014

SVG Export in Drawings

I was intending to blog last night about this, but two beers afterwards and I fell asleep - typical.

The focus now is trying to get the Drawing Module in a usable state, so that people can use it and begin testing. It's unlikely to be in the next 0.14 release, but I would definitely want to see it within the git master so that it can be test and used by the more enthusiastic users.

The remaining pieces of work are exporting the drawing. Last time, I worked on getting SVG templates working. The only issue remaining with these is that they are not automatically redrawn until you update Page properties. I also changed it so that templates provide information about the Page such as the size and orientation, so these don't have to be arbitrarily set by the user.

 I previously mentioned a while ago by using QGraphicsView we can export to a few vector formats for free. This includes PDF, Postcript and also SVG. This is only a temporary measure but is actually very useful to obtain near exact representation of the Drawing shown in the GUI. The limitation is that FreeCAD must be compiled with a GUI to get export functionality. I plan to have a separate Exporter class that will provide an interface for exporting into multiple formats.

There are a few issues with the ViewProvider classes where currently they are not very friendly with any view that isn't a Coin3D view. For the time being the only way to access the SVG export functionality is right clicking the drawing page and clicking on 'Export SVG'. There isn't a way to expose this in the FreeCAD navigation.



Export to SVG from QGraphicsView is pretty easy, it's just the case of using QSvgGenerator and passing this to QPainter and then passing this to the render method inside a QGraphicsView object (m_view)


The Drawing View class manages at a high level the QGraphicsView. The CanvasView (m_view) is the lower level and provides the higher level drawing functionality. CanvasView has two modes to toggle editing. When it is disabled it removes borders, vertices and also cosmetic lines which keep the same thickness regardless of zoom level.

The issue I was having was that the toggleEdit method wasn't working correctly. The output in the SVG file was raster for some reason. 



I knew this was a caching issue but I wasn't entirely sure where it was happening because I explicitly set this to be turned off when out of editing mode. After many hours of searching, this problem was being caused by one line. So the result is below:



 On the left is the exported Drawing opened in Inkscape. The right is the Drawing Module. 

Spot the difference: 
  • The arrow heads, which are drawn as triangles rather than SVG line end styles.
  • The SVG template losing colour for some reason.
  • The font for the dimension datum labels are different, because osifont isn't installed locally on my computer.
  • The drawn primitives within the SVG document are not grouped. 

Note: this will be a fail safe option because we don't have any control on the output at all. For example it would be useful to have groups in SVG to separate views.





Wednesday 19 February 2014

The Return of SVG Templates

After some discussion, there was a little re-think and it seemed a good idea to allow different templates to be used. Despite my focus on creating a parametric template, SVG templates are a reliable solution and have done well in the past.

My previous efforts was adapted to allow different template features to be used and it was fairly trivial to make the SVG template work. There was a lot of code duplication from the previous version which made things even easier without any loss in functionality infact. However it did need a fair few tweaks to get working.

The main change involved parsing the SVG document to obtain the width and height attributes for the document. The problem that I was having was the SVG document didn't share consistent units. What was interesting was using the new Units Framework to parse this, so in theory we shouldn't be restricted to just metric units for templates.

Here's the result:




The title block holders currently don't work at the minute. Anyway there's still more to work to do but it's starting to take shape quite nicely once again.

Friday 7 February 2014

Beginning of parametric (python) templates in the Drawing Module

It's been a passing since the last entry. Unfortunately I've run out of beer and the fridge is empty, so tea again will suffice for a quite casual evening in programming.

After some discussion on the forums, I think I eventually persuaded everyone that SVG templates are simply not right for the job. Admittedly it's a nice standard and is great for customisation and has worked very well in the previous version available in FreeCAD. It also allows easy customisation and post-editing with other graphical editors such as Inkscape.  In fairness, Inkscape was not built for this job, even if there are several attempts at adding CAD functionality into the mix.

The problems using SVG for templates as I see it:

As far as I'm aware it's not adopted by any Mechanical CAD Package. I won't get into the discussion, but the biggest problem with using this template format is that there is no easy way to translate this into other formats such as .dxf, .dwg (Autocad / Teigha) or even our own representation if we ever needed it.

Dealing with XML is not impossible, and can be quite easy to manipulate using DOM (Document Object Model) functionality built into Qt. However, interacting with it through QGraphicsView is not great even if we have QSvg - which is apparently now obsolete. The other original idea was to parse any text fields and turn these into editable text boxes, but this alone creates further impracticalities.

The other big problem that seemed to be happening was the size and variation between templates based primarily on the paper size and the standard used (ANSI, ISO, Arch). There is nothing stopping someone creating these but in the future if these maintained it creates a lot of duplication of work.

I decided that we might as well do it RFT (right first time) rather than wait after the maiden release of the new module, which could be later in the year now.

Parametric driven templates

The combination of having endless combinations of templates was impractical. Some professional Mechanical CAD systems actually have limited number templates available. Instead, there was an attempt to to generate the SVG template using a python script. In the end. the best solution is to use a customisable python script to automatically generate the geometry, text fields and other extras for the template.

This script runs each time page dimensions change and is passed important properties such as page type, width, height, fields required and can create the frame, title blocks and so on, to the user's liking. I'd envisage an interface panel for customising this.

Any template geometry, fields etc. are abstract entities and are stored within the document feature. This can be then easily processed by an export script to be usable in different file formats.

Having abstract types allows isolation of individual elements in a template much easier. Practically this means if a text field is created, a text editing place holder is created and can be more easily manipulated. The same will go for Template annotations which still need work.

The only problem with this method, is we are somewhat restricted to the drawing functions and data types implemented. This might be lines, rectangles, arcs, text. Some CAD programs allow their sketch functionality to be used on top of their drawings. In some cases it can be quite useful, however, considering the maturity of the module, I don't think is appropriate or demanded.

I'll shut up now and show a picture.



This is a square page with a isometric view on it. Those lines across the page were created using

App.ActiveDocument.Template.drawLine(x1,y1,x2,y2);
App.ActiveDocument.Template.touch()

I'm still not sure yet how to organise the script so it knows about Template. However, this is to just show it working. I'm looking for people who can parametrically create a nice python script for generating scripts - don't expect me touching python!

Dimension Placeholders:

Some people will like this. From a solidworks background you can use custom placeholders for dimensions/sketcher datums. It's quite neat and allows some customisation where you may need it. 

For now my implement uses placeholders where there is a content field and the placeholder %value is the datum size.

That's all for  now folks!

Sunday 19 January 2014

Updates to the Drawing Module

I'd promise to get some wrote by the end of the week, so here's my attempt on covering updates I have made to the Drawing Module over pretty much the last half of the year.

In general there's been a lot of incremental small fixes that have accumulated over such a long time, which is a stark contrast when I look at the last blog post on this and might seem significant.

One of the big changes was adding initial support for drawing the page background given the width and height and recently spending time switching the origin of the coordinate system to the bottom left with the y-axis pointing upwards - see this post. QGraphicsView orients with the y-axis pointing downwards which is also used in SVG. It's a trivial fix, where the y coordinate is inverted for the position of every Drawing Views. This is needed to ensure consistency with CAD packages and other formats.

The next step for improving the functionality is adding support for templates and displaying this on the background.



These leads onto talking about further work on improving the dimensions. The most obvious detail is the improved presentation of dimensions. There are now arrow heads, which later will be allowed to be changed to a few standard ISO options and the use of a font called osifont, which I was recommended for a starting point for datum labels. The license needs checking as it appears to be GPL 3 - I'm not entirely sure if this is compatible for distribution directly with the FreeCAD release but in the worst case an be installed separately by the user or made a dependency on the packaging front and be used if available by default.


The datum values can be used calculated as project or as true values - if an orthographic projection is used then projected values are used by default. The leader lines are also calculated to the end points of the lines avoiding any overlapping. The dimensions also use caching and now don't need to recalculate when these are moved on the canvas by the user. 


There is now an orthographic container, which contains ortho-views -orthographic projections such as front, left, top etc. These benefit of having a container is that the child orthoviews are much smarter and allow various properties such as scale or the type of projection (first or third angle) to be set from the container which are then cascaded down to the child views. 

QGraphicsView is quite flexible and allows some nice interactivity too. A little feature I implemented was having alignment between views: and can be interactively moved along one axis. You can seen in the screenshot from above the are all aligned correctly. This originally took a while to figure out because the projection used in the current release of FreeCAD is not consistent - the simple trick was ensuring that the centroid of the part is used as the origin of the projection plane. 


Another little feature I added was support for angles - although there are a few cases where an exception is thrown. The final thing I currently can think of working on is improving the print support which is slowly getting there:




Anyway that's an overview and hopefully give some incentive to give the drawing branch another try!





Monday 13 January 2014

I'm back!

I took some time of for the later part of 2013 for an adventure that in the end didn't work out. Boo hoo!

Now I'm returning back again for 2014 for the foreseeable future! I'm pleasantly surprised to see that people are still actively looking at the pages - despite the inactivity since May and it's remarkable how time has flown. Anyway, let me introduce the new year with some good news.

From last December, I am now a Postgraduate Research student at the EPSRC for Innovation in Additive Manufacturing at the University of Nottingham. (This means I'll be working for a PhD over the next three years). It is a great opportunity to be doing particularly ground breaking research here on various areas concerned essentially with commercial 3D printing and eventually become an expert in this revolutionary field. 

As with all academic research this is non-proprietary, so in theory the modelling techniques that we are aiming to develop may reach into programs such as FreeCAD. I'll later give a brief overview of what we do here now I'm familiar with what projects have been taking place.

I'll later incorporate other posts into this blog related to my research but not exclusive to FreeCAD that might be of interest to some readers. Later on I hope to apply some experiments too. 

So where do I position my self now with FreeCAD? Admittedly these days, I don't have as much time as an undergraduate during the day, but I now have blocks in the evening where I can sufficiently give time to work on it as I choose. 

Drawing Module:

My focus is to tidy up the work that I've done over the past year on the new Drawing Module and get it into a 'playground' state where interested users can test and use it with the strings attached that non-critical bugs exist.

Later on in the week I'll try and write up an update of where I currently am with the Drawing Module - obviously with pictures!

The current big show stoppers in terms of stability and usability are the following:
  • Random Draw Crashes (rare)
  • Random segfaults (rare)
  • Some projections are missing (tangent curves in particular)
  • Dimension of edges lose their position randomly (Bug with OpenCascade)
  • Background template layer non-existant
Note to people: There has been many substantial changes since May. Feel free to check out the git repo - Drawing branch and try it out! 

If you can find some solid test cases for the above in particular that would be very helpful :) 


Friday 31 May 2013

Exams are finished

Yesterday was a momentous occasion. Completing my last exam, I have now finally completed the four years of my degree studying Mechanical Engineering. I guess that's party time for me!

With the unpredictable and quite volatile nature of British weather, there are bound to be a few days that will be pouring with rain, hence an opportunity for further work on getting this drawing module completed.

Over the past week, I have been making a few small refinements, consisting of fixes:

* Preventing a segfault when creating a dimension
* Fix for incorrectly placed dimension - was difficult to locate the bug
* Fixed a rounding error which meant decimals were not being displayed

Dimensions Arrows:

I have also added a support class for displaying dimension arrows, although these are just diagonals at the minute.

'

Having a separate QGraphicsItem class is more useful as it keeps the source code tidy by having the drawing code separate. Also it gives flexibility to manipulate the arrows, such as scaling, flipping etc more universally.

It would also be nice to get the page template working again, but waiting on some work to be ready!

Projected Dimensions:

I spent of time to work on this. Originally I thought this was going to be a difficult task. I thought that to get projected dimensions, I would have to make measurements of projected geometry, which would have been laborious to do. Instead, a quite simple solution is to use the same measurement code for true lengths, but project the measurement vector (direction and length) onto the view plane. Taking our complex case below, there will be a difference between true and projected dimensions.


Taking the top projection of this object and taking dimensions for the corner of each pad the result is below.


The dimension on the far left is the true length, and the right is the projected length. I have attempted to make all dimensions which reference orthographic views to use projected type. 

The next step is to work on getting edge to edge dimensions and angles working. The angles bit is more complicated because the angle value measured is based on the quadrant chosen. 

Wednesday 22 May 2013

Quick experiment again with Sectional Views & General Updates

I am midway during exam season (two weeks) long and things seems to be going swimmingly which I'm happy to report.

Over the past two weeks I've just spent some time tidying up the code and trying to fix a pretty nasty crash in QGraphicsview, anytime you updated the view. I really hope this has gone, but if during testing you suddenly experience a crash when the view updates, please inform me. It seems to have disappeared but esentially was a problem with incorrect bounding boxes as the usual case is. Additionally I've just tidyied up the code and improved the performance by having QGraphicsView using a backend cache, so it doesn't have to constantly redraw features when it is unecessary.

Today, I decided to have a day off revision, as to be honest I am fed up with the mundane repetitiveness. Apart from what I mentioned earlier I wanted to take a quick diversion from the orthographic project stuff I've recently been looking at which I've also made a few improvements on.

I wanted to take a look back at sectional views which I had to give up on because I couldn't correctly produce faces by processing each edges in the correct order. I mentioned this in a previous blog entry some time ago.

Eventually I managed to find the problem and unexpectedly half of the result was from the drawing code itself, where although the edges were in the correct order there was a chance these could be reversed.  Eventually I got something working on most faces.

I then updated the work on the sectional view and behold...


This was taken from a simple planar cut through straight through the centre:


To be honest it's only a proof of concept that i've created over the past few hours. I have identified that some changes are needed to improve the structure to something less 'hacky'. The other limitation is there won't be use of 'true' dimensions because references are lost when the boolean cut is applied.

----------- UPDATE ---------

We all like updates. Spent this evening on it again, rather naughtily and tidied up the areas that I weren't happy with. The section plane is now it's own object in the drawing view, so I had to build up some infrastructure around there which I am more happy with. Now we can finally get some sectioning goodness!



I need to fix a bug that's causing a segfault, so hopefully soon I can push this for people to try and experiment with probably more complicated shapes.