Axonometric (isometric) projection extension

Bug #1362534 reported by Michael Schreier on 2014-08-28
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Michael Schreier

Bug Description

While isometric (or related schemes under the general name of axonometric projections) drawings can be made using the isometric grid, anything but perpendicular lines are hard to do so. It is thus often more convenient to draw each face of an object in front-view and transform it as required.
This is already doable using scale, skew and rotate with the right parameters, however, there are so many wrong "guides" on the web and performing three separate operations* each time an object should be transformed is quite a hassle. Remembering which sign to use for skew and rotate for the right, left and top face is also a constant annoyance.

I've thus written an extension that does this automatically with one click for isometric, "engineer-axonometric" and arbitrary custom axonometric transformations. It is found under Effects -> Render -> Axonometric Tranformation.

What makes the code a bit longer is that does not respect the "do not scale stroke"-setting of the UI so I had to take care of this myself.

With all this being said, would you consider adding the extension to the trunk and/or what changes to the code should be made?

Sorry if this is the wrong place, but I've seen the bug tracker being used for this a few times.

*admittedly one could use the matrix transformation, but the input values are rather unintuitive here and it's still more than one click

Michael Schreier (m-schreier) wrote :
su_v (suv-lp) on 2014-08-28
Changed in inkscape:
importance: Undecided → Wishlist
su_v (suv-lp) wrote :

The extension in the attached 7z archive requires (via INX file) dependencies which are neither met by a default inkscape installation nor included in the archive:

Extension "Axonometric Transformation" failed to load because a dependency was not met.
  type: executable
  location: extensions

Extension "Axonometric Transformation" failed to load because a dependency was not met.
  type: executable
  location: extensions

Extension "Axonometric Transformation" failed to load because a dependency was not met.
  type: executable
  location: extensions

Note: if you import default modules like "copy", "math", "re", "string" in the python script, you don't add them as dependencies for Inkscape to check via INX files (Inkscape cannot check for individual python modules).

Michael Schreier (m-schreier) wrote :

Thanks a lot for the advise!
While writing thisI found an example somehwere that importet a bunch of default modules (in the INX) so I figured I better do the same. Since it didn't raise any errors on my machine I also had no reason to believe otherwise.

Other than this easy to fix issue, any more comments?

houz (houz) wrote :

I just tried this extension and like it a lot. There is just one thing that doesn't work: transforming text. Even when converting it to a path it won't work, I have to ungroup it first and then group it again. According to su_v the script assumes some style settings that might be missing.

Quote from IRC:

<su_v> houz: ok, the extension is lazy and relies on a style property present which may or may not be there
<su_v> probably a quick check whether stroke width is present or not in the individual object would allow it handle more types
<su_v> (it's not related to type, but to default properties added by Inkscape based on current style and other stuff)

Another issue raised by su_v is the placement of transformed faces and if those could be clones instead of duplicates (maybe with a toggle in the dialog to decide if clone or duplicate should be used:

<su_v> I wonder whether it would be possible to align the transformed faces (e.g. of a cube) so that they share a common type of 'origin'
<su_v> if a apply the three different facings to the same group, the results seem to be placed rather randomly (not really, but not where I'd expect them to be)


<su_v> would it be useful to have an option to 'clone and transform clone' instead of 'Duplicate and transform duplicate'?

houz (houz) wrote :

A quick example what this extension can be used for. I drew the three side views on the left and turned them into the projections on the right. A little manual processing is still needed, but it helps a lot to speed this up.

su_v (suv-lp) wrote :

> <su_v> houz: ok, the extension is lazy and relies on a style property
> present which may or may not be there

Pardon me for using 'lazy' in this context - I haven't narrowed down yet what exactly triggers the failure (but AFAICT it seems to be related to the content of the 'style' attribute):

Steps to reproduce:
1) draw a rect, a smaller circle on top of the rect
2) in the XML Editor, remove the style attribute of both objects
3) assign a fill color to each of the objects (via palette below the canvas area)
4) select both and group them
5) apply extension to this group

Traceback (most recent call last):
  File "", line 166, in <module>
  File "/Volumes/magenta/mp-trunk/src/inkscape-repo/mptrunk-quartz-clang/inst/share/inkscape/extensions/", line 261, in affect
  File "", line 160, in effect
    self.replacestackedobjects(newNode, widthattr, strokescale)
  File "", line 97, in replacestackedobjects
    self.replacestackedobjects(o, w, strokescale)
  File "", line 96, in replacestackedobjects
    for o, w in zip(object, widthattr):
TypeError: zip argument #2 must support iteration

Changed in inkscape:
status: New → Confirmed
su_v (suv-lp) wrote :

More observations:
- text objects (as created in Inkscape) are handled ok if the style attribute of the parent <text> object is copy&pasted to the <tspan> element(s)
- clones are handled ok if the style of any regular object is copy&pasted to the clone (see 'Edit > Paste style').

The stroke-width compensation probably needs more checks and fail silently for objects which are not directly affected by stroke scaling of the parent container.

houz (houz) wrote :

Two more things I noticed while playing with the extension:

1) I would like to see an option to keep the stroke widths constant.
2) The top projection seems to rotate in the wrong direction. At least the way I am using it.

PS: Just for the record, I am well aware that the three views projection is wrong, half of it is European and the other half is American. :)

Michael Schreier (m-schreier) wrote :

Thanks for all the input.
As pointed out by the two of you the stroke width compensation is not working as intended (it should in fact ignore objects without the 'style' or 'stroke-width' attribute). It was working for non grouped objects at some points, but apperently the rewritten code fails here (my QA was pretty lazy ;)).
 It shouldn't be all that hard to fix the issue and incorporate the feature requests.
Cloning instead of duplicating will cause an issue with the stroke-width compensation (when an object is to be used for two different views with different compensation factors) though so that feature probably has to be turned off here.
I'll hopefully get to it next week. Thanks again for your efforts.

houz (houz) wrote :

Another thing I noticed: If I group the objects before calling the extension and afterwards ungrouping them I get constant stroke widths (if the preferences allow for optimized transformations). Unfortunately I didn't find any code that easily groups objects and also ungroups again while doing the aforementioned transformation optimization. I don't know if that would be a viable option it might at least give a clue how to make stroke widths as expected.

Michael Schreier (m-schreier) wrote :

Just a heads up:
I've fixed (hopefully) the stroke-width compensation for all cases that were mentioned here and that came to my mind and also adjusted the orientation of the top face (although that is a matter of personal taste) but I'm having some issues with the other requested features.

-Cloning: Am I correct that there is no easy way of doing this? All extensions I had a look at merely duplicated (like I do) the original objects, even if the comments in the code use the term "clone". As far as I can see the only options seems to be to generate a new "use" object and assign the relevant attributes myself.
-Positioning: transforming also affects the object position (i.e. (x0,y0) is not the same position for an object with the transformation attribute applied) and in such a way that I couldn't figure it out myself (scaling is relatively easy, but skewing and rotating left me puzzled). This is obviously automatically corrected when the dialog is used but extensions have to compensate for it on their own. As a workaround I now set the position to (0,0). But even if I knew how to correct the transformation induced position change it won't be possible to do an automatic alignment as that very much depends on the exact shape of an object.

houz (houz) wrote :

The rotation of the top element is broken now – I can't even make a cube any more. So better revert it to what you had before.

Michael Schreier (m-schreier) wrote :

Truly sorry for letting this pass unnoticed (it worked for isometric). It's fixed in the attached version.

houz (houz) wrote :

Thanks a lot, it works like a charm now.

Michael Schreier (m-schreier) wrote :

I've now implemented the option of cloning instead of duplicating an object and all objects are now placed at the position of the original.

The placement of duplicates (not clones!) of _groups_ of objects after the transformation is not yet corrected for as that requires quite extensive adjustments which I didn't bother to figure out yet. As a workaround one could clone the object and break the link after the transformation, but I don't know if that is possible via an extension. I probably won't have enough time to figure this out in the near future so if you don't find any bugs (*fingers crossed*) I'd consider the extension "done".

houz (houz) wrote :

I would prefer if there wasn't an error message that I have to click away when I work with groups (which I do all the time to reliably counter stroke width scalings). Besides that it's great.

Michael Schreier (m-schreier) wrote :

Please excuse my silence, I have been very busy this week.

While removing the warning message only takes as much as commenting out one line it's probably better to have a "corrected" version available here.

jazzynico (jazzynico) on 2015-02-06
Changed in inkscape:
status: Confirmed → In Progress
assignee: nobody → Michael Schreier (m-schreier)
milestone: none → 0.92

Just tried it out in 0.91, great stuff! Thanks!

One small drawback I noticed is that the transformed object can be placed really far away from the original, and that the distance seems (to an end-user) to be quite random.
See example svg's attached or below, if I use the extension on the arc, the transformed object is at quite a distance. In the first file the resulting object is to the right, in the second (where I moved the arc to the left using the select tool and simple drag) the result is to the left of the original.

On attached svg, containing a group of 1 rectangle, 1 circle and two straight paths, the extension doesn't seem to work?
(No transformed object seems to be created).
Inkscape 0.91 on Win7.

Please ignore my previous comment, after restarting Inkscape it worked. Something else must have caused the problem. Apologies for the unnecessary comments. (If anyone can, please remove these last two comments).

Strange behavior with circular gradients:
- make a rectangle
- make a projection of the rectangle (using the extension)
- in the projected rectangle, Fill and Stroke -> set fill to circular gradient
- the gradient axes are also projected (which might be interesting, but maybe not intended?). On moving the endpoints of the gradient's axes however, the angle between the axes changes and is neither 90°, neither corresponding to the projection angle, which makes it rather unusable as gradient. (see attached screenshot)
Inkscape 0.91 on Win7 with axonometric extension posted here on 2014-09-26

jazzynico (jazzynico) on 2016-08-29
Changed in inkscape:
milestone: 0.92 → 0.93
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers