
Constraint Solver (2015) - kasbah
https://www.mattkeeter.com/projects/constraints/
======
henrikeh
A particular flavor of constraint solving is geometric constraint solving,
where constraints such as "this line is parallel to this line" and "this line
is tangent to this curve". This is widely used in pretty much everything
single mechanical CAD tool worth its salt.

But you know what it is missing from: electrical CAD tools.

For footprints this would be especially useful. Some think that footprints are
just one size fits all, but that is far from the truth. Footprints should vary
depending on the environment, production tolerances, manufacturing method.
Right now I have several varieties of the same footprint for different
deratings and uses -- what if I could simply specify a parametric footprint
which actually adapted to specifications made in the design process.

This could be done with wizard programs (several commercial options exists),
but I think an approach based upon geometric constraint solvers and parametric
drawings is a far, far more user-friendly and powerful approach. The
widespread usage in mechanical CAD tools prove that this is not a far-fetched
application; it simply hasn't taken a foothold within electrical CAD tools.

I've been toying with the ideas and researching how it could be done for quite
a while, but I haven't made much code-wise progress yet. However, there is a
lot of tools to draw upon (libraries for geometric constraint solving exists).
If someone is interested in co-developing on some ideas, or already knows of
such a project, then I'd love to hear about it (email is in profile) -- I'm
getting tired of manually calculating grid sizes and offsets.

~~~
sleavey
> geometric constraint solving

Uh oh, that's my trigger word! I've been grappling with this problem recently
and have a lot to say on the matter. I've been trying to build a simple
geometric constraint solver for laying out 2D diagrams of optics in laser
systems. The idea is not to be optically rigorous (for which CAD tools already
exist, like Zemax), but to lay things out in a nice way for publications, such
that lengths and angles can be constrained programmatically. This stems from
when I was writing my PhD thesis and had to edit some 2D optical diagrams. By
changing the angle of one mirror, I had to then move a whole bunch of other
optics around to keep the incidence angle equal to the reflected angle.

I eventually wrote Optivis [1], which was my first attempt at solving the
optical layout problem, but I quickly realised that my simple algorithm didn't
work for cyclicly connected optics, i.e. optics connected back to themselves
in some way. This is the case for any triangular cavity, or e.g. a Mach-
Zehnder interferometer [2]. The problem is that by simply defining length and
angle constraints between lines and optics, you overconstrain the problem when
you connect something back to itself: you are setting an angle or length which
is already implicitly defined by all the other (constrained) angles and
lengths. To properly solve such problems, you must use a geometric constraint
solver - one which can tell whether the problem is under-, well-, or over-
constrained.

With a little research, I found that the traditional CAD approach to solving
this type of problem is to write a bunch of non-linear equations representing
the lengths and angles, and then use a minimiser to solve it based on some
cost function. I wrote a simple library to do this [3], but I found that the
problem had to be drawn with an initial guess close to its final solution in
order for the solver to converge on the solution. Ideally, I wanted to be able
to programmatically draw an optical layout based solely on a set of length and
angle definitions from a file, rather than a prototype drawn e.g. by the user.

I found an academic paper [4] which described a wonderful approach to solving
such a problem. It is based on the idea of "cluster rewriting" instead of
solving non-linear equations. This approach represents constraints as
"clusters", or sets of points, and the relations between them. The algorithm
in the paper supports three types of cluster innately: "rigid" clusters, which
are points with fixed positions with respect to each other; "radial" clusters,
where a set of points are defined to have some fixed length from a central,
rigid point; and "scalable" clusters, which are points whose vertices have
well defined angles but no defined lengths. The algorithm identifies groups of
points that fall into these definitions, and tries to merge them together
until there is only one rigid cluster left. Or, in other words, it starts out
with the initial set of constraints defined by the user, then derives a whole
bunch of implicit constraints on the other points that are consistent with the
initial constraints, provided that the problem is well constrained. What's
awesome about this paper is that the authors provide a Python library [5]. It
was written between about 2009 and 2013 for use with Python 2.5, so I spent a
few weeks over summer porting it to Python 3 [6]. I managed to get it to work,
and it was managing to solve fairly complicated problems, but I found that it
had a few latent bugs which I could not fix easily without really taking time
to understand the full algorithm. For example, when adding a new constraint to
a relatively simple set of points, it would spontaneously move everything back
to the origin. I think I somewhat understand which part of the code is causing
this, but I don't understand it well enough to really fix it.

That's where I left the problem. Recently I have again been looking at
constraint solving using non-linear solvers, particularly with SolveSpace [7],
because its (C++ based) library was recently exposed via Python [8], but this
will again be susceptible to the problem that the user must provide a close-
to-optimal prototype for the system to converge. I am disappointed I couldn't
get the paper's algorithm to work fully, because it is an excellent approach
to this problem. Perhaps someone here has some more experience in this domain
and can help?

I also plan to use whatever I come up with to draw electrical diagrams around
optics. In my field we frequently draw diagrams of optical layouts with the
electrical signals included. For electrical problems you would probably be
more interested in having "neat" signals with 90 degree angles, and parallel
lines, but this would probably be quite straightforward to implement.

[1] [https://github.com/SeanDS/optivis](https://github.com/SeanDS/optivis)

[2]
[https://en.wikipedia.org/wiki/Mach%E2%80%93Zehnder_interfero...](https://en.wikipedia.org/wiki/Mach%E2%80%93Zehnder_interferometer)

[3]
[https://github.com/SeanDS/pygeosolve](https://github.com/SeanDS/pygeosolve)

[4]
[https://www.sciencedirect.com/science/article/pii/S001044850...](https://www.sciencedirect.com/science/article/pii/S0010448509000694)

[5] [http://geosolver.sourceforge.net/](http://geosolver.sourceforge.net/)

[6] [https://github.com/SeanDS/cluster/tree/feature/import-
new](https://github.com/SeanDS/cluster/tree/feature/import-new)

[7] [http://solvespace.com/](http://solvespace.com/)

[8] [https://github.com/KmolYuan/python-
solvespace](https://github.com/KmolYuan/python-solvespace)

~~~
henrikeh
Interestingly I am myself doing a Ph.d. in photonics engineering, but I am
almost entirely in signal processing and information theory.

Anyway, thanks for the links and the thoughts! Amusingly almost all of the
links were already visited! I've looked several times at your library for
geometric constraint solving in Python and almost thought about using it for
my own projects. In the end however I think SolveSpace is the best choice --
it is solid, actively developed and fast.

Your ambition of having the drawings be singularly specified by their
constraints is absolutely admirable, but from my experience it is simple not
feasible nor desirable. First, the optimization problem is difficult to solve
and it will be difficult to specify it such that there is only one unique
solution. Secondly, I think the human provided prototype (through a GUI) is a
critical part of the design process which makes this technology usable. But I
understand the desire to have drawings specified only by constraints.

In the long term, if I am allowed to dream, I'd like to see the development of
a more general purpose constraint-based and parametric drawing library. Right
now I am focused on PCB footprints, but many of same ideas are useful in
electrical diagrams, optical diagrams, GUIs, page layout etc etc. We'll see
how far I get ;)

~~~
sleavey
Nice to see my work is not completely unnoticed, but, you are right to take it
with a grain of salt as I don't actively maintain any of the stuff I linked!

The paper I previously linked discusses the problem of "solution selection" as
you state: the problem of selecting from systems with multiple solutions (for
example, when one specific side of a triangle is constrained onto another
line, it can do so in one of two directions or "orientations" as the paper
refers to them). The paper presents two strategies for selecting solutions: a
selection heuristic approach, whereby the user defines that they want a
certain class of cluster such as one with clockwise angles; and a prototype-
based selection method where the solution which most closely resembles the
user's sketch is selected. I prefer the latter approach, but that's
unfortunately the one that is buggy in the library I found.

I completely agree about how awesome it would be to have a parametric drawing
library. That's actually what my overall goal was to be, eventually, once I
got the optical layout problem solved - there's nothing really to stop such a
library from being generalised to any kind of drawing. I was surprised that I
couldn't find one already, to be honest, as it would no doubt be really useful
in untold applications.

If you manage to get something working, please let me know :-)

------
speps
Please add (2015). Also check out Matt's CAD project:
[https://libfive.com/](https://libfive.com/)

~~~
mayoff
Wow. Any user of OpenSCAD should check out libfive Studio. It looks amazing.

~~~
blt
This is really cool but it looks like the constraint solver [1] is not much
more complex than the one shown in this web page. I really want a program-
driven functional CAD tool like libfive or OpenSCAD, but with powerful 3d
constraint solving like, e.g. Solidworks can provide.

[1]
[https://github.com/libfive/libfive/blob/master/libfive/inclu...](https://github.com/libfive/libfive/blob/master/libfive/include/libfive/solve/solver.hpp)

~~~
pwnna
I've always wanted this as well but I haven't gotten the time to actually look
into writing this. This would solve a lot of complaints I have and have heard
about traditional CAD software, as they tend to constrain you with their very
complex GUI.

~~~
blt
It might not be that difficult to implement a high level DSL around one of the
geometric modeling kernels like Parasolid, ACIS, etc. that form the
computational core of GUI CAD programs. But I don't know if any equally
powerful CAD kernels exist in the open source world.

~~~
sjm-yc-acct
FreeCAD uses Open CASCADE, which is is a free software (LGPL) CAD kernel. Open
CASCADE has a comprehensive modeling API which uses B-rep. For scripting,
FreeCAD has a Python interface. CadQuery is another Python tool (DSL) which is
a plug-in for FreeCAD. FreeCAD itself already has some constraint
functionality.

Libfive is layered and can be used without Studio to generate models with its
extensible Guile Scheme binding. It uses F-rep modeling.

Correct me if I'm wrong, but it should be possible _today_ to add a
programmatic (non-GUI) constraint solver to either FreeCAD or Libfive.

~~~
blt
You are probably right. I realize my previous post sounded pessimistic but I
was only trying to state my ignorance :)

------
c-smile
Hmm, this looks like Cassowary solver that was first used in 1940 as stated
here:
[https://cassowary.readthedocs.io/en/latest/topics/theory.htm...](https://cassowary.readthedocs.io/en/latest/topics/theory.html)

The only difference is that it is using Simplex method instead of gradient
descent (as in article). Simplex and GD are slightly different methods of
finding local minimums in systems of linear equations.

~~~
mayoff
Simplex solves _only_ linear systems, and finds a global optimum.

Cassowary is an incremental version of simplex—it lets you efficiently add,
remove, and modify constraints.

Gradient descent works for non-linear systems, but isn't guaranteed to find
the global optimum.

~~~
jpfr
There is a huge class of non-linear problems where gradient descent (with line
search) is guaranteed to find the global optimum: Convex optimization
problems.

And within convex problems there is a hierarchy of "difficulty": LP ⊂ QP ⊂
SOCP ⊂ SDP

The Simplex algorithm solves only LP. And it was shown that the Simplex has an
exponential worst-case runtime (in the number of constraints). Whereas
interior-point methods (basically variations of Gradient Descent) have a much
better worst-case runtime.

See here for further reference:
[http://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf](http://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf)

------
amelius
Isn't there an incremental way to solve this? Seems a bit wasteful to
recompute everything from scratch for every tiny change in constraints (in the
example for every movement of the mouse).

