Here is a little "preparatory task" that I suggest you start with, before attacking your GUI work. It is not much work, but I believe it will be beneficial both tothe Rebar object and to you to get the hand on the "internal" working of the Rebar object. Basically it implements the points that have been discussed with Bernd in a previous topic, to make the Rebar object ready for any kind of situation. @bernd, feel free to add what you feel is needed to what I explain below.
The current situation:
The current Rebar object is defined in src/Mod/Arch/ArchRebar.py. It is a Part::FeaturePython object (L160), that produces a shape, which is basically a series of tubular objects, made by sweeping a circle along a path, then duplicating that sweep at regular intervals. This is all done in its execute() function (L240).
The circle that is being swept is defined by a Radius property of the Rebar object. The sweeping path is defined by a Base property (inherited from ArchComponent.Component), which is a link to another Part-based object, for example a sketch, or a Draft wire, but any shape that contains at least one wire will work. Before doing the actual sweep (at L290), a fillet is applied to the wire, controlled by the Rounding property (L263)
The problem:
Once the sweep is done, the resulting shape is duplicated a certain amount of times, at a certain interval (L310). This is fine for "straight" elements like a straight beam or a column, where rebars are regularly spaced (ex: stirrups), but falls short in a number of more special situations: curved beams, or irregularly spaced copies (for ex. groups of rebars all based on the same profile but placed at different positions in the beam), or radial situations (in a cylindrical column).
The solution I propose:
I have introduced a couple of weeks ago, a new property type: App::PropertyPlacementList, that hols a list of placements. We could use that property to make the rebar object able to fullfill the problematic situations explained in the above paragraph. At the moment of duplicating the sweeps, we could use a different placement for each duplicate, and therefore we could meet just any situation. I propose therefore to do the following:
- Add a new App::PropertyPlacementList in the Rebar object's __init__() function
- Around (L310), instead of immediately applying the base offset to each duplicate, create a list of placements instead. The first one being a null placement, and the next ones each getting spaced by the base offset.
- Store that list of placements inside our new PlacementList property
- Instead of applying the base offset to each duplicate, apply each placement of the list to each duplicate. So instead of one loop at L310, we will now have two (one that fills the PlacementList, and another that applies the placemetns of the list to each duplicate).
- Move all this code that calculates the Placements list out of execute(), in another function, for example calculatePlacements(). This would allow us, in the future, to build other kinds of Rebar objects, that might calculate the Placements in a different way. Those objects will then just need to override the calculatePlacements() function. That is more or less from L303 to L310, including the changes we will do in the points above.
But, internally, our rebar shapes are not controlled just by a straight array of distances anymore. Each rebar now has its own placement. So the possibilities are now much more. So this sets us right for the future, and we don't build something on a limited data structure anymore. For example, we could now havea complex GUI that calculates the placements directly.
I think this will aslo give you a good grasp at how the Rebar object works internally, which will be very useful for your GUI work later. Also, the list above can be done (and committed) step-by-step, which will help (although you already did pull requests before) getting the whole git / pull request routine rolling too.
What do you think? If anything is not clear, tell me and I'll explain better.