(Solved) Puzzled about fixing a Dynamic Component

I’ve found a useful Spiral Staircase DC from the 3D Warehouse, but there’s a small problem with it that I think I know I ought to be able to fix (but can’t), and a puzzle.

Here’s the component:
Spiral+Stair+DC.skp (249.9 KB)
By default, it draws a spiral stair (I know, the pedants, including me, think it should be a helical stair…, but) looking like this:

There’s an option for a central pole, which I’ve turned off in the Component Options.

But the handrail segments don’t join up.

The angle of slope for the handrail component is given in Attributes as RotX:

and I think the atan(rise/c) should be asin(rise/c), since c is the slope length of the rail calculated as the square root of the sum of its horizontal run (arclen) squared plus the rise squared.

But when I change it, thinking that should fix it, it doesn’t.

First, the angle is still not steep enough, although the formula appears to me to be correct.

Second, If I change the atan to asin in the rail, it only affects the first step.

Yet that step is copied up and round so why do all the Copies still have atan in them, even after I force a redraw of the DC, and even after I save the changed component, close SU, and reopen it?

The Step Component contains the functions to do the copy round and up…

I’m missing something, but can’t see what. Can anyone (perhaps @pcmoor) help me fix the rail angle, on all the steps?

And I’d like optionally to add an inner rail, in cases where there isn’t a pole, and the inner radius is relatively large. I should be able to manage that myself, if I could understand why the outer rail isn’t working correctly.

Well, I thought I might have found an answer to the first part of my question. But I haven’t - it still isn’t quite right, though it’s closer to the right slope for the handrail.

Instead of changing atan(rise/c) to asin(rise/c), I can simply use atan(rise/arclen)

arclen is defined in the rail component inside the first Step as arclen=parent!rail_len, and rail_len is defined in the Step component as

rot_inc is the rotation increment - the angle between successive steps, in radians.

But the multiplier for the outer radius of the steps should (I think) not be the angle itself, but twice the sin of half the angle.

So, instead

Let’s try that…

… and I get a nonsense answer. Maybe needs conversion from radians to degrees first?
That gets closer, but still not quite right, and the formula doesn’t propagate to the copies.

i’d really like to understand how to get the formula for the rail angle to propagate to the copied steps after raising and rotating them, and to be able then to replace the single-edge baluster and rail components with a solid square and round rod respectively.

Do I need to copy the rail components separately and independently of the Step component, not contained within the first Step?

I will take a look at it, however the hand rail would probably be a separate component, the following DCs will help

A helix
the pitch of the line is within another component otherwise there is to much interference from the other rotations.

segmental curves.skp (339.1 KB)

The curve pipe shows how to curve a solid, howbeit only in one plane, to create a helix this way would involve too many parts unless the hand rail is a tube.

arc pipe.skp (776.1 KB)

A concept I used for ligatures is to set it up for a follow me operation, that can be done manually, but quicker with a script


However looking at the new live components, I can’t wait until the authorization is available, as this seems more suited to such curving algorithms.

Thanks, @pcmoor. I’ll look at those examples.

First established that height is to floor levels, then divide by nominated rise, use for steps


This is 14, not 13 as per the original (you could use if copies=copy to hide this last step if required)

Then added attribute for actual rise, if riser is not a divisor, say height is 100”, then use that as the rise value in the Step sub-component


Removed step_theta_radians as redundant

The method of calculation is based on the sweep divided by (steps-1), from this can use the arc/chord formula = 2 x radius x sin(ang/2)


Place formula in rail_len then rename arc_len as more appropriate, then delete rot_inc, as redundant

The rail calculations will then match this, plus the
arc_other_ang = (180- SpiralStair!rot)/2

arc_len = Step!arc_len

change =atan(rise/rail_len)*parent!leftorright to =atan(rise/arc_len)*parent!leftorright as incorrect

I changed c to rail_len

Had to change the context of the rotations, so deleted rise from the rail component and then rotated rotZ =180-Step!arc_other_ang
changed rail axis to end and made another group for the other rotation to match the rise (roty) and lenx to rail_len
*(first I tried the pitch as per original then the arc rotation in the group but that did not work)
STAIRS FIX.skp (460.1 KB)

forgot the reverse
STAIRS FIX.skp (462.8 KB)

set the height to the rise then back again to clear the copied components, the problem is the original definitions are retained, that is why internal copies are not efficient and purges are required to minimum file bloat.

Thanks you, Philip. That’s very helpful.

Using your help, and referring to your example DCs, I’ve been able to recreate a very similar but slightly more versatile DC, more or less from scratch.

It works now to create a single handrail and balusters, both of which are resizable.

I want to make a few further enhancements, then will publish it on the 3D Warehouse. But here’s the present version (saved back to SU v2017 to make it more widely usable).

Spiral+Stair+DC JWM.skp (1.7 MB)

Why is the file so big? I’ve purged it of all unused elements using Model Info/Statistics/Purge unused, there aren’t a lot of edges and faces, and no textures. Is it just because it’s a DC and carries a lot of baggage with it as well as the formulae themselves?

Planned enhancements:

  • add inner handrail
  • add option to hide either or both of inner or outer rails
  • try to line up the outer corners of the treads with the desired stair angle, not as at present, the centrelines of the treads
  • make the treads with rounded inner and outer edges.

My first attempt at doing the third of these resulted in a Circular Reference error - need to try again!

Yes, it took me a while to work that out! If you don’t do that, the older copies hang around with obsolete formulae still in them.

Before I ‘got that’ I had used Outliner to delete all the tread and rail copies.

1 Like

The file bloat and slow regen seems to be an internal coding issue, it maybe why there is a push for live components, though most likely having the ability to run on free and shop is the driving factor. I feel that DCs updating has been sacrificed for this online agenda.
In order to overcome some of the short comings as I have as mention in other posts, I resorted to using scripts. One is to simplfy the DC (hidden deleted; copy collections exploded; shelling and other actions completed: then the parent options frozen and the mess purged) which can be swapped with its definition if you wish to reinstate. The concept of live components seems to do the work in a side program and deliver the result in a simple form in sketchup, not unlike the the simplification idea. My workings have been very customised, but I am starting to see a generic approach.

1 Like

I think I’ve got this pretty well finished, but would welcome any comments to improve it before publishing to the 3D Warehouse.

It now allows you to have visible outer and/or inner, railings, or none, as well as the option of having a central pole of your chosen height and diameter (normally, one would not use a pole with an inner railing). And you can choose the size of balusters and handrail.

The included angle of the staircase now allows for the width of the treads, so that the angle between outside corners of the treads and the centre exactly matches the specified stair included angle.

When you are happy with the size and fit, you can optionally edit the treads to have circular arcs out- and in-side, and to have the line of the tread edges meet at the centre of the staircase.

A few examples:

Reversed direction:

Short rise quarter turn:

Tall and wide:

Medium - domestic room height quarter turn:

Spiral+Stair+DC JWM two-rail.skp (4.3 MB)

Purging the file brings it down to 0.5 MB,
I would make the height fixed to floor finish levels

Since you generate the balustrade separately from the treads (a good idea) I would not generate it if hidden as per options to save a bit

I thought I HAD purged it! Obviously not, since my file was much bigger. Thanks.

I’m not sure I understand what you mean by this.

“Floor finish level” is the height of the final finished floor at the top?

I wondered about whether to make the rise automatically adjust to put the top at ‘target top height’. I decided not to, but to show what rise would be needed to do that, since (perhaps wrongly?) I thought the user might want to know the exact rise needed, and make some other adjustment if it didn’t get to the target height.

The prototype I first found made a bit of a muddle of this, setting the first tread at the user-specified rise, then the others at a greater height to make up the total asked for.

I agree, the DC could make the calculation automatically. It would have to work by first calculating how many steps with the original given rise would fit with the specified rise, then using that to calculate (as I have done) the rise you’d need with that number of steps, and apply it, with a read-only display comparing the two.

I’ll see if I can get that to work.

I agree that is better in principle, but don’t know how to do that.

I’ve had a look at the long list of DC Functions you can use, and still don’t see how to not generate a component other than hiding it.

I’d like to do that, if you could explain how to go about it?

PS. Just spotted a mistake if you generate a stair going ‘up to the right’. The adjustment to create the correct included angle is not working correctly.

It produces the right shape, but not correctly located relative to the centre point.

I’ve just missed somewhere a multiplication by the up_direction variable (+/- 1) for the angle correction.

Fixed that error,

And I’ve made the stairs fit to the exact height using the input Minimum rise value to calculate the number of steps, then dividing that into the Top step height to make the actual rise fit the height exactly.

The revised Component Options:

See later post (no 13) for the final updated DC, saved back to SU v2017.

1 Like

copies=if(Hidden,0,parent!steps_ - 1)

option to hide top step, if copy=copies as trigger

Thank you, I think I understand that now.


@pcmoor, I think I’ve now managed to incorporate all your (very helpful) suggestions.

If either or both railings (rails and balusters) are hidden, then their elements are now not drawn (COPIES = 0), or drawn with zero length and hidden.

I did it slightly differently, with an IF statement setting COPIES to zero if the b5_hide_top_step variable is true. But it works to the same effect.

If the top step is hidden, the rotn_increment is increased to have the next step down complete the Stair included angle (the target angle is divided by steps - 2 instead of steps - 1), leaving one extra rise to the floor top surface.


versus this:

Here’s the updated DC. Unless anyone finds any bugs in the next day or two, this is the version I’ll upload to the 3D Warehouse.
Spiral Stair DC JWM two-rail.skp (530.2 KB)

And here’s the revised list of Component Options

Now uploaded to the 3D Warehouse, at

Spiral stairs dynamic component

1 Like