LDraw.org Discussion Forums

Full Version: Aligning parts using rotation scripts
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
1. Background

A few months ago, I wrote a Lua script for LDCad to animate the rotation of a 4 (or 3) bar linkage, posting the script to the LDraw forum. Writing that script got me thinking about writing a script which would determine the joining point for two parts, each being rotated about their own designated rotation point.

I’ve now written a version of the script. This post describes how to use the script and provides details about downloading and installing the script.

2. Expectations

The aim of the script is to provide a point-and-click mechanism to rotate parts within LDCad. Conceptually, the parts serve different purposes; some are identified as a rotation origin, some are identified as being aligned to another part and some parts are those which are being rotated. Although this post tends to use the term part, the script can also be used with sub-files.

The script provides solutions for two different scenarios
  • rotating a single part to a designated alignment point
  • rotating two parts to a join point common to both parts

Images from an incomplete model of set 9748-1 (a current work-in-progress) illustrate the script's capabilities.
3. Single Part Rotation

Note that the functionality described in this section can be achieved using equivalent capabilities which already exist within LDCad, albeit with a slightly different approach. This functionality was added to provide a slightly simpler point-and-click approach.

Four parts are required for this action, as illustrated in Figure 1:

  1. a part to rotate around,
  2. an alignment part for the part to be rotated,
  3. a fixed part to be rotated to and
  4. the part to be rotated

[Image: 01_single_label.png]
Figure 1 – Single Part Rotation Reference

Existing LDCad Approach

Until recently, the approach I used in LDCad is to temporarily add three extra parts, at positions which correspond to 1, 2 and 3, and then select all three parts in sequence. Via the right mouse click on the first part, I then choose the Selection Info/Show Info menu option as illustrated in Figure 2 (albeit with all other parts / sub-files hidden for the sake of clarity) …

[Image: 02_single_current_01.png]
Figure 2 – Initial part selection

… to toggle the menu item “Show info” from “No” to “Yes” (Figure 3). Once angles are being displayed, the significant angle (highlighted by the red box) can be copied to the clipboard just be clicking on the angle.

[Image: 03_single_current_02.png]
Figure 3 – Displaying angles

The next step is to apply the rotation angle to the appropriate part/sub-file. In this case (illustrated in Figure 4), the first part and the fourth part/sub-file are selected and the Manual rotation dialog invoked via its shortcut key (usually CTRL+r). Selecting the first part as well as the fourth part helps to ensure the fourth part is rotated according to the origin of the first part rather than the origin of the fourth part.

[Image: 04_single_current_03.png]
Figure 4 – Manual Rotation of part

Now for the whoops moment. I often forget which way the positive and negative value for the rotation angle cause an anti-clockwise or clockwise rotation of parts within LDCad. In this case, entering a value of 19.58 caused the part to rotate in the wrong direction so a quick undo (CTRL-z) followed by CTRL+r and making the angle a negative value (i.e. -19.58) results in the desired alignment (Figure 5).

[Image: 05_single_current_04.png]
Figure 5 – Desired part alignment
Rotate one part script approach

The customer rotation scripts provide an equivalent solution for rotating a part. The scripts are accessible via the Scripts/align parts menu item (see this post for installation instructions).

The first step with the alignment functionality is to identify the rotation axis. This is achieved via the menu item Scripts/align parts/Rotation Parameters (see Figure 6). The rotation axis will default to the Y axis, so if the axis around which to rotate to align the parts is either the X or Z axis, the alignment scripts must be notified.

In Figure 6 the parts need to be rotated around the Z axis, hence the Rotation Parameter macro is run. Once selected, the axis of rotation will remain the same until the macro is re-run and a different axis of rotation selected.

[Image: 06_single_new_01.png]
Figure 6 – Rotation Axis Selection

In Figure 6, the supplementary pins which are visible in Figure 3 can be seen. They are coloured red to make it easier to distinguish them from the parts/sub-files which are really part of the model.

To use the single part rotation script, the relevant four parts need to be selected in the order as illustrated in Figure 1. Figure 7 illustrates the four parts (the three supplementary pins and the sub-file which contains the leg) selected in readiness to run the script.

[Image: 07_single_new_02.png]
Figure 7 – Single Part Rotation Part Selection

Once the parts have been selected, the open scripts/align parts menu (Figure 8) and then select the Rotate one part menu item. If any number other than four parts have been selected, a dialog window will appear that prompts with the part selection requirements to run the script.

[Image: 08_single_new_03.png]
Figure 8 – Align Parts Menu

After the script has been run, the parts will be rotated and a dialog displayed that allows the rotation to be accepted or discarded (Figure 9).

[Image: 09_single_new_04.png]
Figure 9 – Rotate One Part Dialog

Closing the dialog by clicking Yes results in the rotation being applied to the model (Figure 10). At this point, the user should manually delete any supplementary parts being used purely to achieve the desired rotation.

[Image: 10_single_new_05.png]
Figure 10 – Model after One Part Rotation

By itself, the Rotate one part script is not much different to using the approach described earlier in the Existing LDCad Approach section. The primary difference is not having to establish and specify the rotation angle. However, the code used to rotate one part is available for re-use when attempting to align two rotating parts.
4. Two part rotation

The rotation alignment script can also be used to rotate two parts and identify the points at which the parts can be connected. This scenario was the primary driver for the scripts – the single part rotation came as a consequence of implementing the two part rotation.

This description starts with a simple test case. The benefit of doing this is that the concepts can be more readily illustrated without having superfluous parts acting as a distraction.


Six parts are required for the two part rotation action, as illustrated in Figure 11.
  1. a part around which the first part will be rotated
  2. an alignment part for the first part to align with the second rotating part
  3. a part around which the second part will be rotated
  4. an alignment part for the second part to align with the first rotating part
  5. the first part to be rotated
  6. the second part to be rotated
[Image: 11_double_sample_01.png]
Figure 11 – Two part rotation, reference parts

The parts which are used for the purpose of rotation and alignment are selected first (Figure 12). The premise of selecting these parts first is that there is less “noise” from the highlighted selected parts than if the parts which are to be rotated were selected first (which could make it harder to subsequently select the rotation and alignment parts).

[Image: 12_double_sample_02.png]
Figure 12 – Two part rotation, rotation and alignment selection

Once the parts to be rotated have been selected, the menu item Scripts/align parts/Rotate two parts is selected (Figure 13) …

[Image: 13_double_sample_03.png]
Figure 13 – Rotate two parts menu item

… and the parts will be rotated immediately. There are usually two potential points at which the parts could be joined. Therefore, one part will be rotated to one of the positions and the other part will be rotated to the second position. A dialog is displayed allowing the user to choose which one is the desired position (Figure 14).

[Image: 14_double_sample_04.png]
Figure 14 – Rotate two parts, choose alignment position

Figure 15 and Figure 16 Illustrate the difference between selecting the first and second position for this example model.

[Image: 15_double_sample_05.png]
Figure 15 – Rotate two parts, first position selected

[Image: 16_double_sample_06.png]
Figure 16 – Rotate two parts, second position selected

Once the parts have been rotated into the desired position, any of the rotation or alignment parts which are surplus to requirements can be deleted.
5. Two Part Rotation Actual Usage

Enough with the simplistic example. Let’s see how to use the script in a more realistic way using an actual model.

Figure 17 illustrates a partial build of set 9748-1. The four rotation and alignment parts required for the two part rotation are highlighted. The two red pins are required to achieve the rotation but are not part of the model so they will be deleted once the rotation is complete.

[Image: 17_double_r2d2_01.png]
Figure 17 – Two Part Rotation, R2D2 #1

Figure 18 shows the selection of the four rotation and alignment parts.

[Image: 18_double_r2d2_02.png]
Figure 18 – Two Part Rotation, R2D2 #2

Figure 19 illustrates all 6 “parts” selected, immediately prior to invoke the Rotate Two parts script.

[Image: 19_double_r2d2_03.png]
Figure 19 – Two Part Rotation, R2D2 #3

Figure 20 illustrates the two positions where the rotated parts can be aligned.

[Image: 20_double_r2d2_04.png]
Figure 20 – Two Part Rotation, R2D2 #4

Figure 21 shows the model after the first alignment position was selected and the superfluous alignment and rotation parts (the red pins) deleted. Note the liftarms at the rear still need to be aligned …

[Image: 21_double_r2d2_05.png]
Figure 21 – Two Part Rotation, R2D2 #5

… which can be achieved using the single part alignment, as illustrated in Figure 22. Once again, additional parts have been added to the model for rotation/alignment purposes.

[Image: 22_double_r2d2_06.png]
Figure 22 – One Part Rotation, R2D2 #6

Figure 23 shows the placement of the liftarms after completion of the one part rotation and the deletion of the extra red rotation/alignment pins.

[Image: 23_double_r2d2_07.png]
Figure 23 – One Part Rotation, R2D2 #7

This sample model shows how the rotation scripts support a point-and-click approach within LDCad for aligning parts, thus avoiding the need for a user to have to compute rotation angles
6. Installation

The Lua scripts which provide the logic to achieve the part rotation are available for anyone to download and use.

Assuming you have downloaded and extracted the scripts from the zip file, the suggested installation process is as follows;
  1. If you are currently running LDCad, exit the program,
  2. Locate the directory in which LDCad is installed. This will likely be something like C:\Program Files\LDCAD. Next, navigate to the sub-directory called scripts.
  3. If you do not have a sub-directory named custom within the scripts sub-directory, create it.
  4. Navigate to the custom sub-directory.
  5. If you do not have sub-directories within custom named global and modules, create any that are required.
  6. Place the script named align parts.lua into the global sub-directory. Place the script named compound_rotation.lua into the modules sub-directory.
  7. When you next start LDCad, under the Scripts menu item, you should see a new menu item named align parts within the list of global modules.
7. Other Comments/Observations

There is a reasonable degree of commonality between the code contained in these scripts and the code in the linkages.lua. This is deliberate.  Somewhere on my To Do list is an action to rewrite the linkages.lua scripts so that it uses the code within compound_rotation.lua.

I think that the part alignment logic works for all cases. However, it you encounter a situation in which they don’t appear to work as you expect, please post to this thread and I will see if I can identify the issue.

This is my second attempt at writing some Lua scripts. It seems likely that there are aspects of the scripts which can be improved. Constructive feedback is welcomed.

Roland, you are more than welcome to include/distribute these scripts as part of LDCad, should you so wish. Feel free to fold, mutilate or spindle them should the need arise.


Wonderful! I can't wait to try it. I have one suggestion you may want to consider, regarding the selection order.

As you know, the two-part rotation is also somewhat present in LDCad using Selection Info, this time with the triangle function. But again, you have to manually copy the rotation angles and apply them yourself (although this time the program correctly decides which direction to rotate).

In LDCad's existing behavior, the selection order for this method is endpoint, rotation center, rotation center, endpoint. You could emulate this behavior in the script by simply swapping points 1 and 2 in the selection order. (I think selecting the actual parts to be moved last is a good idea.)

This would also match the behavior of Roland's custom right angle script, which is used to rotate a part so that it rests against an unknown point on a plane, such as a ladder leaning against a wall. In that script you select 1) the endpoint of the part being rotated, 2) the rotation center, and 3) a point on the plane that is normal to the rotation center.

Not a big deal, of course, just something that might make the integration more seamless.
(2021-12-16, 16:18)N. W. Perry Wrote: [ -> ]...

As you know, the two-part rotation is also somewhat present in LDCad using Selection Info, this time with the triangle function. But again, you have to manually copy the rotation angles and apply them yourself (although this time the program correctly decides which direction to rotate).


This would also match the behavior of Roland's custom right angle script, which is used to rotate a part so that it rests against an unknown point on a plane, such as a ladder leaning against a wall. In that script you select 1) the endpoint of the part being rotated, 2) the rotation center, and 3) a point on the plane that is normal to the rotation center.


I wasn't aware of the triangle function until your post! A helpful observation for me to take on board. I'll see if I receive any other feedback before making changes. Modifying the part selection order is a straight forward change (it will probably take me longer to redraw the images in this thread).


David, I do not know how to thank you enough! I tested your script for linkage animation and it works nicely but I must say I have not spent much time with it because I was so curious about part alignment scripts. And I'm impressed how well they work - including bells and whistles like showing two possible alignment options directly in the model, without affecting later undo stack. You did a great job and  helped me with my next models a lot. Thanks again, David, for such nice Christmas present!

And for a motivation how can I help with this. Because this is such a good base it would be pity not to expand it to be helpful in more situations. For example hinges do not have any "central pivot part" your script needs. LDCAD does not allow neither user nor scripts work with snap objects, AFAIK. (And as I remember past conversations with Roland,it is not easy to implement in current LDCAD code.) So I'm thinking about some special helper parts...

Another improvement is using current coordination system instead of the global one. To make script works for setups rotated in any way - just select a part, press "O" to get local coordination system, and continue with the script as usual.
Pages: 1 2 3