Constraints UI (FreeCAD)

Ideas for improving the constraints UI in FreeCAD. These are some ideas that I have been thinking about since I first used FreeCAD in 2015.

It is lovely feature of FreeCAD that you can create a 2D drawing by the use of constraints — specifying geometry in terms of relationships such as “line A must be horizontal, the same length as line B, and tangential to arc C”. However, in FreeCAD at the moment this feature is confined to the Sketcher and segregated from the standard drawing tools such as those in the Draft workbench.

I’d like constraints to be available much more generally. On the FreeCAD discussion forum I asked last year if anyone has any grand plans and DanielC asked recently why Draft and Sketcher are separate. I have some ideas about how I think CAD should work, with and without constraints. I decided to expand on my ideas in writing in order to share them and improve them based on other people’s ideas. Maybe I will eventually turn the ideas into working code, or maybe someone else will.

Sketching a Face

The Sketcher documentation says a sketch is intended to be used to draw a single face, perhaps with holes in it, or alternatively to draw a set of features (pockets or pads) on an existing face. This means the sketch should consist of one or more closed and non-intersecting outlines. The Sketcher user interface currently provides no assistance with keeping to this rule: it allows freely scattering any set of disjoint and intersecting lines and even isolated points. Blender, by contrast, features a user interface in which the user can build a complex shape by starting with a simple shape and successively modifying it, at all times choosing actions that maintain the closed shape, never creating arbitrary disconnected or intersecting edges. This style can be seen in Yorik’s Blender tutorial where in step 4 he starts with a small square and by extending it in various ways creates a complex floor plan. That user interface is explicitly modelling a face, whereas Sketcher draws a line drawing which is only implicitly to be thought of as representing a face.

Sketching a face is an important task, and it makes sense to have a user interface that explicitly supports this task. Such a UI would explicitly support drawing a face, by ensuring its boundary line (and those of any holes) remains closed and non-intersecting. It would indicate which area is inside and which is outside, by colouring the area of the face. It would provide more tools which modify the shape of the face directly while keeping it a valid face, like the Blender tools mentioned above, such as the (already existing) fillet tool. It would still support arbitrary lines and points as construction geometry.

Real Physical Shapes

A basic concept is that we usually want to model a real physical shape rather than an abstract mathematical kind of geometry. Regardless whether we are drawing the outline of a single face or a much more general drawing, this has at least two consequences. As a user I expect the sign or handedness of dimensions to be preserved: the right-angle at a convex corner is not the same as the right-angle at a concave corner. And a real object has a non-zero size.

Elements (except points) have non-zero size. Examples:

  • line length != 0 (else degenerate to a point)
  • circle/arc radius != 0 (else degenerate to a point)
  • arc angle != 0 (else degenerate to a point)

Dimension constraints are “signed” and angles are “handed”: there is no ambiguity between positive and negative or left and right. (Failure to apply this principle has led to the “Flipping Problem” documented in this Sketcher tutorial, which has plagued FreeCAD for a long time.)

Signed distance:

  • x-position, y-position
  • x-distance, y-distance
  • point-to-line distance (sign indicates which side of the line the point is on, relative to the line direction)
  • parallel-lines distance (sign indicates which side the second line is on, relative to the first line’s direction)

Signed (or “handed”) angle, with range of a full 360°:

  • absolute orientation
  • arc start and end angles
  • relative angle

Some dimensions are unsigned (just a magnitude):

  • point-to-point distance
  • line length
  • circle/arc radius

Some apparently dimensionless constraints are effectively a signed value, although the magnitude is implied and only the sign is apparent to the user. (See Zero or Special Value Constraints below.) Examples:

  • horizontal, vertical line (sign indicates direction)
  • parallel, tangent (sign indicates relative directions)
  • perpendicular (sign indicates handedness relative to the two directions)

Solving the Flipping Problem

In 2015 I wrote a patch to test the idea of making the constraints signed or handed. To make it simple I implemented all the angle-related constraints, including special cases such as “horizontal” and “vertical”, in terms of the same basic numeric angle constraint code, removing all the optimized implementations of the special cases. The result seemed to robustly preserve topology, exhibiting no flipping.

I didn’t finish it or contribute it back to the project yet. I ought to at least put it in GitHub. Here it is as a patch:

2015-solve-flipping-1.patch

Zero or Special Value Constraints

Some common constraints can be defined as a user-interface alias for a certain value of a dimension constraint. Examples:

  • Coincident <-> point-to-point distance or H- and V-distances = 0
  • Point-On-Line <-> point-to-line distance = 0
  • H-align, V-align <-> V-, H-distance = 0
  • Horizontal, Vertical <-> absolute orientation = 0°, 180°, ±90°
  • Parallel, Perpendicular <-> relative angle = 0°, 180°, ±90°

The system need not remember whether the user entered a zero dimension as numeric zero or by its special name, and the user interface should always show the special name in preference to numeric zero.

The system may prefer to implement each special value constraint either using the general dimension implementation with a value of zero or using a special-case implementation. For example, some comments in the forums indicate that FreeCAD’s constraint solver works well only when the special-case implementations are used.

Basic Constraint Types

A fairly complete set of the most basic constraint types, including both dimensioned forms and zero or special value forms where possible. Note that the current Sketcher UI does not include line-to-line distance.

I have changed some of the icons, such as absolute angle, to better indicate their specific meaning; I would also like to change those for absolute h- and v-position.

Length and Distance

32px-Constraint_Length 32px-Constraint_Radius point-to-point distance / radius

32px-Constraint_HorizontalDistance 32px-Constraint_VerticalDistance absolute h- / v- / h- and v-position

32px-Constraint_HorizontalDistance 32px-Constraint_VerticalDistance h- / v-distance

32px-Constraint_PointOnPointcoincident (point-to-point or h- and v- distance = 0)

point-to-line distance

32px-Constraint_PointOnObject point on line (point-to-line distance = 0)

Constraint_Line_Line_Distance_1 line-to-line distance

32px-Constraint_Tangent tangent (line-to-line distance = 0)

Orientation and Angle

Constraint_AbsoluteAngle_1 absolute angle (orientation)

32px-Constraint_Horizontal 32px-Constraint_Vertical horizontal (abs. angle = 0° or 180°) / vertical (90° or -90°)

relative angle

32px-Constraint_Parallel 32px-Constraint_Perpendicular parallel (rel. angle = 0° or 180°) / perpendicular (90° or -90°)

Basic Relationships

32px-Constraint_EqualLength equal dimension

Complex Relationships

Some examples of more complex relationships. I would not consider these to be basic constraints.

32px-Constraint_Symmetric symmetry around a point (h- and v-distances negative of the other) or line (h- and v-distances related to the other)

32px-Constraint_SnellsLaw Snell’s law relating two angles

Constraint_Parallel_Distance Parallel at a distance (combination of parallel and line-to-line distance)

[-·-] Tangent continuation (combination of tangent and coincident)

User Interface

  • When editing a constraint of a type which has both a dimensioned form and a zero form (e.g. Point Distance From Line and Point On Line), provide an option to switch it to the other form.

Snapping is Constraint (FreeCAD)

Thinking about the Sketcher UI in FreeCAD

Snapping is Temporary Constraint

Sketcher Constraints help us to position a new point coincident with an existing point, or to set the angle of a new line parallel with an existing line, and so on. This relationship is stored, and the actual position is calculated from the relationship.

Draft Snap also helps us to position a new point coincident with an existing point, or to set the angle of a new line parallel with an existing line, and so on. However, only the new position is stored; the fact that this position was determined by a relationship with another object is immediately forgotten.

Notice that there is a lot of overlap in the available kinds of Sketcher constraint and the available kinds of Draft Snap. There are snaps that correspond more or less closely with each kind of constraint, and vice-versa. That should not be surprising.

Coincident 32px-Constraint_PointOnPoint <-> 32px-Snap_Endpoint 32px-Snap_Midpoint 32px-Snap_Center Endpoint / Midpoint / Centre

Point on line 32px-Constraint_PointOnObject <-> 32px-Snap_Near 32px-Snap_Extension Nearest / Extension

Lock X and Y 32px-Sketcher_ConstrainLock <-> 32px-Snap_Grid Grid intersection

Horizontal / Vertical 32px-Constraint_Horizontal 32px-Constraint_Vertical <-> 32px-Snap_Ortho Orthogonal

Parallel / Perpendicular 32px-Constraint_Parallel 32px-Constraint_Perpendicular <-> 32px-Snap_Parallel 32px-Snap_Perpendicular Parallel / Perpendicular

Both Snapping and Constraints have the same purpose: to determine the placement (position and/or orientation) of an object in terms of a relationship with either another object or the world coordinate system. The difference is that a constraint is stored in terms of its definition, whereas with snapping only the resulting placement is stored.

Snapping implies that there is some significant feature to snap to, and that the user wants the new object to have this relationship to that existing feature. A useful, intuitive behaviour would be:

  • snapping is available for every kind of constraint that relates to existing geometry
  • snapping always produces a stored constraint (if the user wants it)

In Sketcher there is an auto-constraint option that produces a stored constraint automatically for some kinds of constraint, including coincident point, point on line, tangent, horizontal, vertical; but not parallel, perpendicular, equal length, etc. One or more icons appear near the cursor to indicate what kind of constraint will be produced.

Sketcher also performs some limited snapping (to a point and to a grid intersection only, AFAICT). Like with Draft Snap, it just stores the resulting position (with no constraints applied) when snapping takes place and auto-constraint is not enabled.

For the record, a couple more features are closely related to constraints:

  • temporarily constraining movement to an axis during an operation such as Move is much the same thing as snapping, and likewise should generate a stored constraint
  • a Draft Dimension is similar to a non-driving constraint

How It Should Work

This is what I’d like to have.

  • Draft and Sketcher should both support snapping in the same way and with all the types of snap;
  • every type of snap should be able to produce a (stored) constraint in Sketcher;
  • consistent naming and icons between snapping and constraints, and between Draft and Sketcher;
  • consistency between Draft Dimensions and Sketcher Dimension Constraints (both driving and non-driving).

Snapping should be an easy, fast and intuitive method of entering most constraints.

 

Boot Rack

BootRack-Drawing2-Sample

Ever since we moved here I’ve been wanting to build something out of wood. A boot rack for the porch is an ideal first project. I’d love to build a solid, heavy work bench first, which would make all future woodworking much easier than using the garden wall as a sawing horse, but I chose to make this first. It can serve as a practise piece: a boot rack will immediately be useful even if it’s a bit rough around the edges or indeed all over, whereas a wobbly work bench would be worthless.

Isometric Delight

Searching for graph paper in my stationery drawer I came across an old pad of isometric drawing paper. What a delight! Sketching ideas and making neat scale drawings on that was as much fun as building the thing.

Of course I want to make drawings like these on the computer as well. One of the most exciting things computers could do, for me as a teenager, was CAD. I had lots of ideas about how my own CAD program would work. I recall programming a snap-to-nearest-point feature, in a mixture of BASIC and Z80 assembly language, which was very satisfying. Nowadays we have 3D CAD, even in the Open Source Software world where the best 3D modelling software by far is the truly excellent Blender. Its emphasis is on artistic rendering, whereas in second place is FreeCAD which is more suited to designing mechanical parts, and includes a constraint-based 2D drawing capability (“this line shall be the same length as that one”, etc.). FreeCAD is quite usable, but both its capabilities and its user interface need a lot of work to match the quality of Blender.

I started using FreeCAD because of the constraint drawing approach and because it looks like it would be fun and feasible to join in with developing it.

In case you are interested, you may download the FreeCAD project file here and open it in FreeCAD. (I was using FreeCAD v0.16.)

BootRack-r722.fcstdBootRack-r722.fcstd

Recycled Wood

I made a list of parts using the wood sizes available from DIY supermarkets, but thinking of my friend Andy who set up the Southampton Wood Recycling Project, I drove over to East Midlands Wood Recycling CIC in Derby to see what they had. From their stock of long pieces I chose rough sawn pine to use for the back legs and bracing batons and a planed, rounded-edge larger piece for the front legs. The staff voluntarily cut the leg pieces into shorter lengths for me. From their main room full of piles of wood, I chose some cedar planks in various widths for the shelves. I liked the cedar because it was already varnished and because it smells lovely, but I have found it rather brittle and weak to be a good choice for shelves. I might add more strengthening batons underneath the front edges to prevent it from snapping when I perch my foot on it to tie my laces.

A Lesson

I learnt a lesson. Mixing many sizes of wood made for much more work than if I’d made all the legs the same size and all the batons the same size.

hCard versus Gravatar

My ‘avatar’ is a small image of my face that is shown next to comments that I made, to identify me, on this blog and on many social networks.

Gravatar Gravatar

I uploaded my avatar to Gravatar.com which is a service that stores the avatars of millions of people and provides them to any social media web sites that want to display them. The main reason to use Gravatar is that whenever I want to update my image, I only need to do so once, in this one place, rather than updating it on the configuration pages of every social networking system I use.

My blog, running the WordPress.org software, is one of the many systems that fetches my avatar from Gravatar. In fact WordPress, by default, seems to only allow me to use Gravatar and not even to provide an option to host my own image directly.

But why should I use a third-party service? I want to host my personal identification at my own domain.

hCard microformat microformats

There’s already an Open protocol for publishing an identifying image of myself: the hCard microformat and specifically its “photo” property*. That’s more or less the same thing as an avatar. Gravatar even provides a user’s profile data as an hCard, including their avatar, as well as providing the avatar through its own Gravatar Image Requests protocol.

Anyone can implement hCard on their own domain just by inserting some static HTML markup. I’ve done it on my own site.

So if I have my domain why should I use Gravatar rather than hosting my own hCard?

Thoughts

  • If the Gravatar Image Requests protocol is much more useful than just serving a single static image, then my domain could host a service serving my own avatar through the Gravatar protocol. Instead of popular web sites assuming that they will fetch my avatar from (conceptually) www.gravatar.com/avatar/<me@my-domain> they should then fetch it in the same way but from an address like <my-domain>/avatar/<me>.
  • Any self-hosted software, such as WordPress.org, that can fetch my avatar from Gravatar should also offer the option of fetching it directly from my domain, in order to not force me to use a particular third-party service.
  • Although it would be nice, I wouldn’t expect a silo system to offer that option. They surely gain advantages such as efficiency by using a single third-party system to provide the avatars of all their users. However, Gravatar could offer the option to act as a proxy server for my own domain.

Can we design a system that retains any significant benefits of the Gravatar system while allowing me to host my data myself?

Is there at least a WordPress plug-in that provides something towards this?

Would parts of Gravatar’s protocol be a useful complement to the hCard protocol capabilities?


  • There is also an hCard “logo” property. There is also h-card, the microformats2 successor to hCard, with corresponding “u-photo” and “u-logo” properties.

 

 

Blog bug: invalid security certificate

If you try to read this blog using an https:// URL, your browser will probably warn you that the security certificate is not valid.

Why is this? It’s because I have hosted the blog on Red Hat’s OpenShift service and I haven’t yet installed my own security certificate. When you visit https://blog.foad.me.uk the connection is redirected to a server whose real address is <something>.rhcloud.com. The web server there currently provides a security certificate that cryptographically proves the content comes from rhcloud.com but doesn’t say anything about blog.foad.me.uk.

What does the warning mean? It means the certificate, and therefore your browser, can’t prove that the content you are seeing really comes from my domain. If you are connecting through a compromised network then it’s possible a man-in-the-middle attack could present a spoof web site that pretends to be blog.foad.me.uk. A spoof web site might try to trick you into giving it your credit card details, for example.

I’m working on setting up my own certificate.

Hmm… I’ve just started reading up about it and it looks a bit more complicated than I thought.

Blog bug fixed: inability to leave a comment

If you have tried to leave a comment on this blog and it didn’t work, I apologise.

Two days ago I found out that commenting was working properly only if you were signed in (e.g. with or or ) or if you were using an https:// URL (which has its own bug). Otherwise, the “Send” button either did nothing or in some cases displayed a “wrong Captcha code” error message even though you had entered the correct code.

I haven’t been able to find the root cause of the problem. I presume it is related to the wpDiscuz plug-in which I use to handle comments.

Yesterday I disabled the Captcha feature, which seems to have fixed the problem. As a bonus, that also lowers the barrier to leaving a comment. I have other spam protection measures in place. If those prove insufficient I’ll revisit the decision.

Thanks to R for reporting the problem.

Indie Web

Have you heard about the Indie Web? The idea that our habit of always using a “silo” company like Facebook, WhatsApp or Twitter to communicate with our friends will ultimately hurt our society. The idea that we should re-decentralise the Web by taking back individual control of our data and communications.

A rant

Almost every message we send or photo we post, in recent years, we do by depositing it in a silo. We give our message or photo to a company such as Facebook, and let them store it on their terms. We let them control when and how and to whom they show our message. We even let them control whether and how we can get our own data back from them*. That system works just fine, of course. You can be my Friend and talk to me; all you need to do is sign up and keep to their terms of service. As long as I accept that they may start charging me for the service at any time. And as long as I don’t care that when they eventually shut down the service my diaries and albums will be gone, and all the links to them will be dead even though I kept a copy of the data somewhere else.

The silo system works fine, as long as we don’t mind not sharing our conversation and photos with some of our real friends and family who can’t or won’t join Facebook or prefer to use another system. And as long as I’m happy to log in to a different service to read my LinkedIn messages, and another one to read WhatsApp, and can’t download all my messages into a single application and go offline and then read them.

Good old email

What happened to email? It’s the only popular Internet communication medium that is still Open in the sense that anyone can join in without having to sign up to one particular company. Email has wonderfully opened up the world by being an Open protocol. That’s hugely important.

The Internet connects us all directly. It was designed that way. Technically, each of us could directly own and control our own data, our own communications, everything we do on the Internet — our own “digital self”. But we are choosing not to, and perhaps we don’t appreciate the implications this choice will have.

You might want to read Dan Gillmor explaining Why the Indie Web movement is so important.

The movable blog

When I write a blog article like this one, I should have the choice where to store the text, and that choice should not restrict who can read it.

Can you tell where this blog post you’re reading is actually stored and being served from? If you’re a geek you’ll know how to find out, but I’ll tell you: at RedHat’s OpenShift Online service. At least, at the time of writing, it was. If RedHat ever starts charging too much for that service, I can rent another server from another company, or even buy one and put it under my desk, and move the blog data and software onto it and continue running.

How? The key here is:

The URLs of my data and of my communication channels are under my own domain name:

http://<my-data>.foad.me.uk

http://blog.foad.me.uk/this-blog-entry

When I first experimented with setting up a blog, I set it up at jfoad.wordpress.com because that’s the Easy Way and it was only a private test with about two posts. Even so, before I realised what I was doing, I’d sent my brother a link to one of those posts. Then I moved the blog to a server under my own control, which meant it could no longer be at a wordpress.com address, and so the link in his email became broken. I broke the hyperlink. I Broke The Web. Oops.

To be able to move my blog to a different hosting company without breaking the Web, my URLs need to stay the same. To achieve this, the URLs need to be under my complete control, which means under my own domain name. I learnt the lesson and moved it to blog.foad.me.uk.

When I next need to move it, I will adjust my DNS records for the URL blog.foad.me.uk to point to the new server, and so the URLs of all the posts can stay the same, and all existing links to them can remain unbroken.

Indie Web

I’ve been learning about Indie Web principles, and I’ve been playing with some specific techniques in practice, but the movement has a lot of catching up to do. Two big obstacles we need to overcome are the enormous “network effect” that makes it hard for users to escape from the dominance of the big silo companies, and the lack of good, open protocols and methods that are easy to set up and delightful to use. In order to overcome the former we’ll need to create the latter, and that’s something I’m getting interested in helping with.

Let’s go and IndieWebify.Me


* Data protection law in Europe requires Them to let Us retrieve all the data they hold about us, hence Google “Takeout”, Facebook “Download my data”, and so on. That’s something, but it does not make an Indie Web.

My Own Email Address with Forwarding

Part 5 of “My Own Email Address”.

I’ve set up my own julian@ email address with Fastmail.

I have set up my Fastmail account to forward all incoming emails to my Gmail account, where I can read them just as if they had been addressed to my Gmail address. By configuring my Gmail account to add my new address as an additional sender, I can also reply to those messages and send new messages with my new address in the “From” field. For offline use I have configured Thunderbird similarly with the new address as one of multiple sending “identities” attached to my Gmail account.

At first I set up a regular user email account with Fastmail, and tried it out for a couple of days. Their email web interface is very good, and their whole system seems to be well designed and what I’d call “sensible”, which is a term of high praise from me. However, I decided for the time being to do a minimal migration, only changing my email address, and not also migrating my mail storage to a Fastmail mailbox and using Fastmail’s web interface. There are enough issues to deal with just changing address.

Now I am happy that the new address is stable — I am not going to be messing around in ways that will break it — I’ll want to start using it. One tedious step is to change all my registrations on web sites. That won’t be so hard, because only six months ago I went through the same process changing to my Gmail address and creating new passwords, and I was careful to save the results in my password manager so I know where to find them all this time around.

But updating registrations isn’t a high priority. It’s more important to me that I use my own address for personal communication, where people will notice it. (Maybe I should send out a mass “change of address” email, though I hate those.)

Even more important right now is to be able to use my own address on software engineer job applications.