Saturday, 3 November 2018

Playing Lego With Python - Pile 'Em High...

With the Build Matrix now functioning correctly I could increase the number of bricks that I could add to my pile hopefully without experiencing any intersections.  I set the total number of bricks to 100 and pressed "Go"...


Not too bad!  Analysing the model I was fairly certain it was a valid model - that is, that every brick was connected to another brick by at least one stud and there were no intersections or "floaters" (bricks that hung in space and were not connected to any other brick).  If I imported my model into Lego Digital Designer (LDD) - LDD would generate an error and tell me how many bricks were incorrectly placed...My Lego tower imported into LDD with no errors - so I created a couple more towers and imported those too...


LDD reported no errors for any of the piles (phew!) - it looks like the changes I made to the build matrix seem to be working.


Having created a mechanism for adding a variety of Lego bricks to a model in a valid (if somewhat unstable configuration) could I now get the code to start to create more visually interesting models and designs.  


Friday, 2 November 2018

Playing Lego With Python - Improving The Build Matrix

Managing the addition of both rotated bricks and "odd" bricks like 1x2 and 2x3 required me to rework the "Build Matrix" that I use to track the placement of bricks as they added to the ldr file.


You can see the build matrix in the image above on the left (along with the ldr file and the ldview image.  This tracks each brick as it's added to the .ldr file and calculates the studs and dimensions of the bricks.  This allows the code to track the placement of each brick as it's added to both the .ldr file and the build matrix. 

I also re-orientated the build matrix so that it matched the top view - this is where the single red stud buried in the top right hand corner of the model became important as it provided a reference point on model that I could match to the matrix - and the stud is buried in the plate so as not to effect the actual build matrix itself.


The problem I had was in the mechanism I used to calculate the addition of the new part to the build matrix - once I had reworked that calculation, the build now matrix accurately reflects the placement of bricks in the ldr file.  However, if you look carefully at the build matrix you can spot that the build matrix only works by moving the bricks up in height (look at the matrix values for the bottom two "floating" pink studs) - there is currently no option to "back-fill" into holes.  This should be possible by combining the build matrix and the data stored in the ldr file so that you could also map the "holes" between bricks that might exist in a model.


With the build matrix now accurately reflecting the addition of parts which had been rotated, or were "odd" bricks (or both!) I could now consider building much taller towers hopefully without any placement errors.





Thursday, 1 November 2018

Playing Lego With Python - Rotating Bricks During The Build


Whilst brick rotation is relatively straight forwards (by modifying the rotation matrix for each brick in the ldr file) tracking the corresponding rotation in my build matrix (which tracks brick dimensions and stud availability of bricks in the pile) is complex.  As you rotate the brick you have to rotate and reshape the brick matrix by the same amount.



Although the Lego piles were increasingly "correct", that is to say that any new bricks sat on top an existing stud if one was available in its proposed position there were still occasional problems in the build matrix.  I realised the problems seemed to limited to specific bricks (mainly "odd" flavour bricks like 1x2 and 2x3 bricks and plates) - the placement of these "odd" bricks is trickier as the origin point of the bricks in ldr brick placement does not place "odd" bricks on a stud by default, so they immediately need moving to sit on a stud.  This initial move and any subsequent move needs to be tracked in the build matrix and then also tracked when these bricks were rotated.






Consequently I've had to learn a lot about matrix manipulation!

Tuesday, 2 October 2018

Playing Lego With Python - Building More Complex Brick Piles


I'm  now adding increasing  variety and number of bricks to my brick piles - I have included both bricks and plates and the bricks currently remain the "even" flavour of bricks - so 2x2, 2x4 etc.








The problem now is the orientation of the all bricks - they are all pointing in the same direction.  So now I need to think about rotating the bricks...



Monday, 17 September 2018

Playing Lego With Python - Adding More Brick Shapes

I've stated to add other Lego parts to my models - particulaly asymetrical bricks, both bricks and plates, which are more difficult for my code to process and understand.  I now can now build towers with a variety of bricks.





But there are still some issues with brick placement!




Wednesday, 5 September 2018

Playing Lego With Python - High Hopes!

I updated my build tracking matrix to better monitor the position of the bricks being added to the LDR file - it's not perfect but I've reduced the intersecting bricks down to about 4% - Here's a build with about 55 bricks - LDD told me there were 2 intersections (you can just see one of them at the base).  I underestimated the importance of the build tracking matrix when I started this project - I probably need to go back an rework it!



 

Thursday, 30 August 2018

Playing Lego With Python - Can Computers Play With Lego?

I've been working on some code to allow Python to "understand" the structure of LEGO bricks. In LDRAW, the actual LDR file contains each brick used in a given LEGO model (the .ldr file contains information about the colour, position, and orientation of a given brick). By drilling down into the individual structure of a given brick (by analysing the sub part dat files that create each brick) I could get python to understand the dimensions of the brick and the number of studs that a brick has. Using this information I could then begin to place bricks and get the code to place subsequent bricks with an understanding of the bricks that might already exist on the model. Remember that the ldr file of the model itself doesn't contain information about the dimensions of the brick or the stud count of the bricks, so my python code has to work this out for itself. When the code places a subsequent brick it has to make sure that it doesn't intersect with any existing bricks already in the model. Currently I'm simply using 2x2 standard bricks - these are by far the easiest to initially manipulate in code as they are symmetrical, but ultimately I'd like my code to manipulate a range of bricks perhaps around 10 different bricks - this may seem small but the possible model combinations using 10 bricks would run into the billions! Currently the code displaces any new bricks in height (Z) when it encounters an existing brick (as this is easier than displacing left right in X and Y!) 






Tracking the existing bricks (and their dimensions) during the build remains challenging and whilst it generally works there are still instances where the code misplaces a LEGO brick causing an intersection. These intersections - and occasional "floaters" (where a brick seems to hang unsupported) still require additional debugging. I also deliberately embed a red stud in the base plate for orientation purposes (if you were wondering what that was!) 




There is no "intelligence" here so this is definitely not an AI or any type of machine learning, but if I could get some code to understand the "structure" of LEGO bricks it might be possible to to use this code as the basis for an AI experiment, where it might be possible to build and analyse 1000's of lego models very quickly and select those that might be more "appealing" than others - any kind of AI or ML is a considerable way off for me currently but if anyone in interested in exploring the idea of a model building LEGO AI please get in touch info@cultofthebrick.co.uk