diff --git a/geosolver/clsolver2D.py b/geosolver/clsolver2D.py index ad1598b..13cc65d 100644 --- a/geosolver/clsolver2D.py +++ b/geosolver/clsolver2D.py @@ -4,6 +4,10 @@ The solver finds a generic solution for problems formulated by Clusters. The generic solution is a directed acyclic graph of Clusters and Methods. Particilar problems and solutions are represented by a Configuration for each cluster. + +Note: this module is now depricated, and will be removed or replaced +in the future. + """ from clsolver import * diff --git a/geosolver/clsolver3D.py b/geosolver/clsolver3D.py index fa875f4..d8fb120 100644 --- a/geosolver/clsolver3D.py +++ b/geosolver/clsolver3D.py @@ -301,8 +301,8 @@ class MergePR(ClusterMethod): res = conf1.merge(conf2) elif isroot2: res = conf2.merge(conf1) - else: # cheapest - res = conf2.merge(conf1) + else: # cheapest - just copy reference + res = conf2 return [res] class MergeDR(ClusterMethod): @@ -344,8 +344,8 @@ class MergeDR(ClusterMethod): res = conf1.merge(conf2) elif isroot2: res = conf2.merge(conf1) - else: # cheapest - res = conf2.merge(conf1) + else: # cheapest - just copy reference + res = conf2 return [res] class MergeRR(ClusterMethod): @@ -386,7 +386,7 @@ class MergeRR(ClusterMethod): res = conf1.merge(conf2) elif isroot2 and not isroot1: res = conf2.merge(conf1) - elif len(c1.vars) < len(c2.vars): # cheapest + elif len(c1.vars) < len(c2.vars): # cheapest - transform smallest config res = conf2.merge(conf1) else: res = conf1.merge(conf2) @@ -495,8 +495,8 @@ class DeriveTTD(ClusterMethod): def prototype_constraints(self): constraints = [] - constraints.append(FunctionConstraint(fnot(is_left_handed),[self.a,self.b,self.c,self.d])) - constraints.append(FunctionConstraint(fnot(is_right_handed),[self.a,self.b,self.c,self.d])) + constraints.append(SelectionConstraint(fnot(is_left_handed),[self.a,self.b,self.c,self.d])) + constraints.append(SelectionConstraint(fnot(is_right_handed),[self.a,self.b,self.c,self.d])) return constraints class DeriveDAD(ClusterMethod): diff --git a/geosolver/geometric.py b/geosolver/geometric.py index d4cb080..baa9278 100644 --- a/geosolver/geometric.py +++ b/geosolver/geometric.py @@ -3,7 +3,7 @@ problems incrementally.""" import vector from clsolver import PrototypeMethod -from clsolver2D import ClusterSolver2D +# depricated! from clsolver2D import ClusterSolver2D from clsolver3D import ClusterSolver3D from cluster import Rigid, Hedgehog from configuration import Configuration @@ -95,6 +95,16 @@ class GeometricProblem (Notifier, Listener): else: con.add_listener(self) self.cg.add_constraint(con) + elif isinstance(con, RigidConstraint): + for var in con.variables(): + if var not in self.prototype: + raise StandardError, "point variable not in problem" + #if self.get_rigid(con.variables()) + # raise StandardError, "rigid already in problem" + #else: + if True: + con.add_listener(self) + self.cg.add_constraint(con) elif isinstance(con, SelectionConstraint): for var in con.variables(): if var not in self.prototype: @@ -212,7 +222,7 @@ class GeometricProblem (Notifier, Listener): class GeometricSolver (Listener): """The GeometricSolver monitors changes in a GeometricProblem and - mappes any changes to corresponding changes in a GeometricCluster + maps any changes to corresponding changes in a GeometricCluster """ # public methods @@ -261,26 +271,33 @@ class GeometricSolver (Listener): self._add_constraint(con) def get_constrainedness(self): - toplevel = self.dr.top_level() - if len(toplevel) > 1: - return "under-constrained" - elif len(toplevel) == 1: - cluster = toplevel[0] - if isinstance(cluster,Rigid): - configurations = self.dr.get(cluster) - if configurations == None: - return "unsolved" - elif len(configurations) > 0: - return "well-constrained" - else: - return "over-constrained" - else: - return "under-constrained" - elif len(toplevel) == 0: - return "error" + """Depricated. Use get_statis instead""" + return self.get_status() + # toplevel = self.dr.top_level() + # if len(toplevel) > 1: + # return "under-constrained" + # elif len(toplevel) == 1: + # cluster = toplevel[0] + # if isinstance(cluster,Rigid): + # configurations = self.dr.get(cluster) + # if configurations == None: + # return "unsolved" + # elif len(configurations) > 0: + # return "well-constrained" + # else: + # return "over-constrained" + # else: + # return "under-constrained" + # elif len(toplevel) == 0: + # return "error" def get_result(self): - """returns the result as a GeometricCluster""" + """Depricated. Use get_cluster instead.""" + return self.get_cluster() + + def get_cluster(self): + """Returns a GeometricCluster (the root of a tree of clusters), + describing the solutions and the decomposition of the problem.""" map = {} # map dr clusters for drcluster in self.dr.rigids(): @@ -326,7 +343,6 @@ class GeometricSolver (Listener): geoin = map[incluster] geoout = map[outcluster] geoout.subs = list(geoin.subs) - # determine top-level result rigids = filter(lambda c: isinstance(c, Rigid), self.dr.top_level()) @@ -338,7 +354,7 @@ class GeometricSolver (Listener): result.solutions = [] result.flags = GeometricCluster.UNSOLVED elif len(rigids) == 1: - # structurally well constrained + # structurally well constrained, or structurally overconstrained result = map[rigids[0]] else: # structurally underconstrained cluster @@ -348,6 +364,53 @@ class GeometricSolver (Listener): result.subs.append(map[rigid]) return result + def get_solutions(self): + """Returns a list of Configurations, which will be empty if the + problem is not structurally well-constrained. Note: this method is + cheaper but less informative than get_cluster. The + list and the configurations should not be changed (since they are + references to objects in the solver).""" + rigids = filter(lambda c: isinstance(c, Rigid), self.dr.top_level()) + if len(rigids) == 0: + return self.dr.get(rigids[0]) + else: + return [] + + def get_status(self): + """Returns a symbolic flag, one of: + GeometricCluster.S_UNDER, + GeometricCluster.S_OVER, + GeometricCluster.OK, + GeometricCluster.UNSOLVED, + GeometricCluster.EMPTY, + GeometricCluster.I_OVER, + GeometricCluster.I_UNDER. + Note: this method is cheaper but less informative than get_cluster. + """ + rigids = filter(lambda c: isinstance(c, Rigid), self.dr.top_level()) + if len(rigids) == 0: + return GeometricCluster.EMPTY + elif len(rigids) == 1: + drcluster = rigids[0] + solutions = self.dr.get(drcluster) + underconstrained = False + if solutions == None: + return GeometricCluster.UNSOLVED + else: + for solution in solutions: + if solution.underconstrained: + underconstrained = True + if drcluster.overconstrained: + return GeometricCluster.S_OVER + elif len(solutions) == 0: + return GeometricCluster.I_OVER + elif underconstrained: + return GeometricCluster.I_UNDER + else: + return GeometricCluster.OK + else: + return GeometricCluster.S_UNDER + def receive_notify(self, object, message): """Take notice of changes in constraint graph""" if object == self.cg: @@ -412,6 +475,15 @@ class GeometricSolver (Listener): self.dr.add(rig) # set configuration self._update_constraint(con) + elif isinstance(con, RigidConstraint): + # map to rigid + vars = list(con.variables()); + rig = Rigid(vars) + self._map[con] = rig + self._map[rig] = con + self.dr.add(rig) + # set configuration + self._update_constraint(con) elif isinstance(con, FixConstraint): if self.fixcluster != None: self.dr.remove(self.fixcluster) @@ -422,6 +494,9 @@ class GeometricSolver (Listener): self.dr.add(self.fixcluster) self.dr.set_root(self.fixcluster) self._update_fix() + elif isinstance(con, SelectionConstraint): + # add directly to clustersolver + self.dr.add(con) else: ## raise StandardError, "unknown constraint type" pass @@ -482,6 +557,13 @@ class GeometricSolver (Listener): conf = Configuration({v0:p0,v1:p1}) self.dr.set(rig, [conf]) assert con.satisfied(conf.map) + elif isinstance(con, RigidConstraint): + # set configuration + rig = self._map[con] + vars = list(con.variables()) + conf = con.get_parameter() + self.dr.set(rig, [conf]) + assert con.satisfied(conf.map) elif isinstance(con, FixConstraint): self._update_fix() else: @@ -529,15 +611,17 @@ class GeometricCluster: I_UNDER incidental under-constrained S_OVER structural overconstrained S_UNDER structural underconstrained - UNSOLVED unsolved + UNSOLVED unsolved (no input values) + EMPTY empty (no variables) """ - OK = "well constrained" + OK = "well-constrained" I_OVER = "incidental over-constrained" I_UNDER = "incidental under-constrained" S_OVER = "structral over-constrained" S_UNDER = "structural under-constrained" UNSOLVED = "unsolved" + EMPTY = "empty" def __init__(self): """initialise an empty new cluster""" @@ -602,7 +686,7 @@ class FixConstraint(ParametricConstraint): """A constraint to fix a point relative to the coordinate system""" def __init__(self, var, pos): - """Create a new DistanceConstraint instance + """Create a new FixConstraint instance keyword args: var - a point variable name @@ -698,4 +782,36 @@ class AngleConstraint(ParametricConstraint): +str(self._variables[2])+","\ +str(self._value)+")" +class RigidConstraint(ParametricConstraint): + """A constraint to set the relative position of a set of points""" + + def __init__(self, conf): + """Create a new DistanceConstraint instance + + keyword args: + conf - a Configuration + """ + ParametricConstraint.__init__(self) + self._variables = list(conf.vars()) + self.set_parameter(conf.copy()) + + def satisfied(self, mapping): + """return True iff mapping from variable names to points satisfies constraint""" + result = True + conf = self._value + for index in range(1,len(self._variables)-1): + p1 = mapping[self._variables[index-1]] + p2 = mapping[self._variables[index]] + p3 = mapping[self._variables[index+1]] + c1 = conf.map[self._variables[index-1]] + c2 = conf.map[self._variables[index]] + c3 = conf.map[self._variables[index+1]] + result = tol_eq(distance_2p(p1,p2), distance_2p(c1,c2)) + result = tol_eq(distance_2p(p1,p3), distance_2p(c1,c3)) + result = tol_eq(distance_2p(p2,p3), distance_2p(c2,c3)) + return result + + def __str__(self): + return "RigidConstraint("+str(self._variables)+")" + diff --git a/geosolver/selconstr.py b/geosolver/selconstr.py index 1f95ffa..579e19d 100644 --- a/geosolver/selconstr.py +++ b/geosolver/selconstr.py @@ -2,92 +2,9 @@ from constraint import Constraint from tolerance import tol_eq from intersections import * + class SelectionConstraint(Constraint): - """constraints for solution selection""" - -class NotCounterClockwiseConstraint(SelectionConstraint): - """select triplets that are not counter clockwise (clockwise or degenerate)""" - - def __init__(self,v1,v2,v3): - """init constraint with names of point variables""" - self._variables = [v1,v2,v3] - - def satisfied(self, map): - """return True iff mapping from variable names to points satisfies constraint""" - p1 = map[self._variables[0]] - p2 = map[self._variables[1]] - p3 = map[self._variables[2]] - return not is_counterclockwise(p1,p2,p3) - - def __str__(self): - return "NotCounterClockwiseConstraint("\ - +str(self._variables[0])+","\ - +str(self._variables[1])+","\ - +str(self._variables[2])+")" - -class NotClockwiseConstraint(SelectionConstraint): - """select triplets that are not clockwise (counterclockwise or degenerate)""" - - def __init__(self,v1,v2,v3): - """init constraint with names of point variables""" - self._variables = [v1,v2,v3] - - def satisfied(self, map): - """return True iff mapping from variable names to points satisfies constraint""" - p1 = map[self._variables[0]] - p2 = map[self._variables[1]] - p3 = map[self._variables[2]] - return not is_clockwise(p1,p2,p3) - - def __str__(self): - return "NotClockwiseConstraint("\ - +str(self._variables[0])+","\ - +str(self._variables[1])+","\ - +str(self._variables[2])+")" - -class NotObtuseConstraint(SelectionConstraint): - """select triplets that are not obtuse (acute or degenerate)""" - - def __init__(self,v1,v2,v3): - """init constraint with names of point variables""" - self._variables = [v1,v2,v3] - - def satisfied(self, map): - """return True iff mapping from variable names to points satisfies constraint""" - p1 = map[self._variables[0]] - p2 = map[self._variables[1]] - p3 = map[self._variables[2]] - return not is_obtuse(p1,p2,p3) - - def __str__(self): - return "NotObtuseConstraint("\ - +str(self._variables[0])+","\ - +str(self._variables[1])+","\ - +str(self._variables[2])+")" - -class NotAcuteConstraint(SelectionConstraint): - """select triplets that are not acute (obtuse or degenerate)""" - - def __init__(self,v1,v2,v3): - """init constraint with names of point variables""" - self._variables = [v1,v2,v3] - - def satisfied(self, map): - """return True iff mapping from variable names to points satisfies constraint""" - p1 = map[self._variables[0]] - p2 = map[self._variables[1]] - p3 = map[self._variables[2]] - return not is_acute(p1,p2,p3) - - def __str__(self): - return "NotAcuteConstraint("\ - +str(self._variables[0])+","\ - +str(self._variables[1])+","\ - +str(self._variables[2])+")" - - -class FunctionConstraint(SelectionConstraint): - """select solutions where function returns true when applied to given variables""" + """select solutions where function returns true when applied to given variables.""" def __init__(self,function, vars): """init constraint with function and a sequence of variables""" @@ -102,7 +19,7 @@ class FunctionConstraint(SelectionConstraint): return apply(self._function, values)==True def __str__(self): - return "FunctionConstraint("+self._function.__name__+","+str(map(str, self._variables))+")" + return "SelectionConstraint("+self._function.__name__+","+str(map(str, self._variables))+")" def fnot(function): notf = lambda *args: not apply(function,args) @@ -110,7 +27,7 @@ def fnot(function): return notf def test(): - print FunctionConstraint(is_right_handed, ['a','b','c','d']) - print FunctionConstraint(fnot(is_right_handed), ['a','b','c','d']) + print SelectionConstraint(is_right_handed, ['a','b','c','d']) + print SelectionConstraint(fnot(is_right_handed), ['a','b','c','d']) if __name__ == "__main__": test() diff --git a/solvertest/test.py b/test/test.py similarity index 95% rename from solvertest/test.py rename to test/test.py index 87f48d4..9157cad 100644 --- a/solvertest/test.py +++ b/test/test.py @@ -1,5 +1,5 @@ -# Geometric constraint solver test -# See below for simple use of the GeometricSolver API +"""This module provides some tests for the GeoSolver. +The tests are also simple examples of how to use of the GeomSolver API""" from geosolver.geometric import * from geosolver.vector import vector @@ -10,6 +10,30 @@ from time import time # ---------- 3D problems ----- +def block(name,x,y,z): + """A block with variables name+#1...8 and dimensions x,y,z""" + problem = GeometricProblem(dimension=3) + problem.add_point(name+'#1', vector([0.0, 0.0, 0.0])) + problem.add_point(name+'#2', vector([0.0, 0.0, 0.0])) + problem.add_point(name+'#3', vector([0.0, 0.0, 0.0])) + problem.add_point(name+'#4', vector([0.0, 0.0, 0.0])) + problem.add_point(name+'#5', vector([0.0, 0.0, 0.0])) + problem.add_point(name+'#6', vector([0.0, 0.0, 0.0])) + problem.add_point(name+'#7', vector([0.0, 0.0, 0.0])) + problem.add_point(name+'#8', vector([0.0, 0.0, 0.0])) + conf = Configuration({ + name+'#1':vector([-x/2, -y/2, -z/2]), + name+'#2':vector([-x/2, -y/2, +z/2]), + name+'#3':vector([-x/2, +y/2, -z/2]), + name+'#4':vector([-x/2, +y/2, +z/2]), + name+'#5':vector([+x/2, -y/2, -z/2]), + name+'#6':vector([+x/2, -y/2, +z/2]), + name+'#7':vector([+x/2, +y/2, -z/2]), + name+'#8':vector([+x/2, +y/2, +z/2]) + }) + problem.add_constraint(RigidConstraint(conf)) + return problem + def fix3_problem_3d(): """A problem with a fix constraint""" problem = GeometricProblem(dimension=3) @@ -737,7 +761,7 @@ def stats_solving(): problem = random_triangular_problem_3D(size,10.0,0.0,0.0) t1 = time() solver = GeometricSolver(problem) - result = solver.get_constrainedness() + result = solver.get_status() t2 = time() t = t2-t1 print size,"\t",i,"\t",t,"\t",result @@ -754,7 +778,7 @@ def stats_incremental(): constraint = random.choice(problem.cg.constraints()) problem.rem_constraint(constraint) problem.add_constraint(constraint) - result = solver.get_constrainedness() + result = solver.get_status() t2 = time() t = t2-t1 print size,"\t",i,"\t",t,"\t",result @@ -776,7 +800,7 @@ def stats_parametric_incremental(): #problem.rem_constraint(constraint) #problem.add_constraint(constraint) #constraint.set_parameter(constraint.get_parameter()) - result = solver.get_constrainedness() + result = solver.get_status() t2 = time() t = t2-t1 print size,"\t",i,"\t",t,"\t",result @@ -792,7 +816,7 @@ def stats_parametric(): constraint = random.choice(problem.cg.constraints()) t1 = time() constraint.set_parameter(constraint.get_parameter()) - result = solver.get_constrainedness() + result = solver.get_status() t2 = time() t = t2-t1 print size,"\t",i,"\t",t,"\t",result @@ -813,6 +837,7 @@ def runtests(): #test(random_distance_problem_3D(10,1.0,0.0)) #test(fix1_problem_3d()) #test(fix2_problem_3d()) - test(fix3_problem_3d()) + #test(fix3_problem_3d()) + test(block("BB", 4.0,2.5,5.0)) if __name__ == "__main__": runtests() diff --git a/solvergui/angleDialog.py b/workbench/angleDialog.py similarity index 100% rename from solvergui/angleDialog.py rename to workbench/angleDialog.py diff --git a/solvergui/camera.py b/workbench/camera.py similarity index 100% rename from solvergui/camera.py rename to workbench/camera.py diff --git a/solvergui/cameraHandler.py b/workbench/cameraHandler.py similarity index 100% rename from solvergui/cameraHandler.py rename to workbench/cameraHandler.py diff --git a/solvergui/cluster.py b/workbench/cluster.py similarity index 100% rename from solvergui/cluster.py rename to workbench/cluster.py diff --git a/solvergui/commands.py b/workbench/commands.py similarity index 100% rename from solvergui/commands.py rename to workbench/commands.py diff --git a/solvergui/compositionView.py b/workbench/compositionView.py similarity index 100% rename from solvergui/compositionView.py rename to workbench/compositionView.py diff --git a/solvergui/constants.py b/workbench/constants.py similarity index 100% rename from solvergui/constants.py rename to workbench/constants.py diff --git a/solvergui/cvitems.py b/workbench/cvitems.py similarity index 100% rename from solvergui/cvitems.py rename to workbench/cvitems.py diff --git a/solvergui/debug.py b/workbench/debug.py similarity index 100% rename from solvergui/debug.py rename to workbench/debug.py diff --git a/solvergui/distanceDialog.py b/workbench/distanceDialog.py similarity index 100% rename from solvergui/distanceDialog.py rename to workbench/distanceDialog.py diff --git a/solvergui/examples/rick/boat.gcs b/workbench/examples/rick/boat.gcs similarity index 100% rename from solvergui/examples/rick/boat.gcs rename to workbench/examples/rick/boat.gcs diff --git a/solvergui/examples/rick/hexahedron.gcs b/workbench/examples/rick/hexahedron.gcs similarity index 100% rename from solvergui/examples/rick/hexahedron.gcs rename to workbench/examples/rick/hexahedron.gcs diff --git a/solvergui/examples/rick/ninepoint.gcs b/workbench/examples/rick/ninepoint.gcs similarity index 100% rename from solvergui/examples/rick/ninepoint.gcs rename to workbench/examples/rick/ninepoint.gcs diff --git a/solvergui/examples/rick/octahedron.gcs b/workbench/examples/rick/octahedron.gcs similarity index 100% rename from solvergui/examples/rick/octahedron.gcs rename to workbench/examples/rick/octahedron.gcs diff --git a/solvergui/examples/rick/randomproblem.gcs b/workbench/examples/rick/randomproblem.gcs similarity index 100% rename from solvergui/examples/rick/randomproblem.gcs rename to workbench/examples/rick/randomproblem.gcs diff --git a/solvergui/examples/rick/three_bananas.gcs b/workbench/examples/rick/three_bananas.gcs similarity index 100% rename from solvergui/examples/rick/three_bananas.gcs rename to workbench/examples/rick/three_bananas.gcs diff --git a/solvergui/examples/rogier/2tetra.gcs b/workbench/examples/rogier/2tetra.gcs similarity index 100% rename from solvergui/examples/rogier/2tetra.gcs rename to workbench/examples/rogier/2tetra.gcs diff --git a/solvergui/examples/rogier/2tetra1a.gcs b/workbench/examples/rogier/2tetra1a.gcs similarity index 100% rename from solvergui/examples/rogier/2tetra1a.gcs rename to workbench/examples/rogier/2tetra1a.gcs diff --git a/solvergui/examples/rogier/2tetra2.gcs b/workbench/examples/rogier/2tetra2.gcs similarity index 100% rename from solvergui/examples/rogier/2tetra2.gcs rename to workbench/examples/rogier/2tetra2.gcs diff --git a/solvergui/examples/rogier/a2d1.gcs b/workbench/examples/rogier/a2d1.gcs similarity index 100% rename from solvergui/examples/rogier/a2d1.gcs rename to workbench/examples/rogier/a2d1.gcs diff --git a/solvergui/examples/rogier/block.gcs b/workbench/examples/rogier/block.gcs similarity index 100% rename from solvergui/examples/rogier/block.gcs rename to workbench/examples/rogier/block.gcs diff --git a/solvergui/examples/rogier/diamond.gcs b/workbench/examples/rogier/diamond.gcs similarity index 100% rename from solvergui/examples/rogier/diamond.gcs rename to workbench/examples/rogier/diamond.gcs diff --git a/solvergui/examples/rogier/doubletetra.gcs b/workbench/examples/rogier/doubletetra.gcs similarity index 100% rename from solvergui/examples/rogier/doubletetra.gcs rename to workbench/examples/rogier/doubletetra.gcs diff --git a/solvergui/examples/rogier/example1.gcs b/workbench/examples/rogier/example1.gcs similarity index 100% rename from solvergui/examples/rogier/example1.gcs rename to workbench/examples/rogier/example1.gcs diff --git a/solvergui/examples/rogier/example2.gcs b/workbench/examples/rogier/example2.gcs similarity index 100% rename from solvergui/examples/rogier/example2.gcs rename to workbench/examples/rogier/example2.gcs diff --git a/solvergui/examples/rogier/example3.gcs b/workbench/examples/rogier/example3.gcs similarity index 100% rename from solvergui/examples/rogier/example3.gcs rename to workbench/examples/rogier/example3.gcs diff --git a/solvergui/examples/rogier/example4.gcs b/workbench/examples/rogier/example4.gcs similarity index 100% rename from solvergui/examples/rogier/example4.gcs rename to workbench/examples/rogier/example4.gcs diff --git a/solvergui/examples/rogier/example5.gcs b/workbench/examples/rogier/example5.gcs similarity index 100% rename from solvergui/examples/rogier/example5.gcs rename to workbench/examples/rogier/example5.gcs diff --git a/solvergui/examples/rogier/hull.gcs b/workbench/examples/rogier/hull.gcs similarity index 100% rename from solvergui/examples/rogier/hull.gcs rename to workbench/examples/rogier/hull.gcs diff --git a/solvergui/examples/rogier/hulltest.gcs b/workbench/examples/rogier/hulltest.gcs similarity index 100% rename from solvergui/examples/rogier/hulltest.gcs rename to workbench/examples/rogier/hulltest.gcs diff --git a/solvergui/examples/rogier/newblock.gcs b/workbench/examples/rogier/newblock.gcs similarity index 100% rename from solvergui/examples/rogier/newblock.gcs rename to workbench/examples/rogier/newblock.gcs diff --git a/solvergui/examples/rogier/overconstrained.gcs b/workbench/examples/rogier/overconstrained.gcs similarity index 100% rename from solvergui/examples/rogier/overconstrained.gcs rename to workbench/examples/rogier/overconstrained.gcs diff --git a/solvergui/examples/rogier/table.gcs b/workbench/examples/rogier/table.gcs similarity index 100% rename from solvergui/examples/rogier/table.gcs rename to workbench/examples/rogier/table.gcs diff --git a/solvergui/examples/rogier/test.gcs b/workbench/examples/rogier/test.gcs similarity index 100% rename from solvergui/examples/rogier/test.gcs rename to workbench/examples/rogier/test.gcs diff --git a/solvergui/examples/rogier/test2.gcs b/workbench/examples/rogier/test2.gcs similarity index 100% rename from solvergui/examples/rogier/test2.gcs rename to workbench/examples/rogier/test2.gcs diff --git a/solvergui/examples/rogier/test3.gcs b/workbench/examples/rogier/test3.gcs similarity index 100% rename from solvergui/examples/rogier/test3.gcs rename to workbench/examples/rogier/test3.gcs diff --git a/solvergui/examples/rogier/test4.gcs b/workbench/examples/rogier/test4.gcs similarity index 100% rename from solvergui/examples/rogier/test4.gcs rename to workbench/examples/rogier/test4.gcs diff --git a/solvergui/examples/rogier/tetra-over.gcs b/workbench/examples/rogier/tetra-over.gcs similarity index 100% rename from solvergui/examples/rogier/tetra-over.gcs rename to workbench/examples/rogier/tetra-over.gcs diff --git a/solvergui/examples/rogier/tetra-overconstrained.gcs b/workbench/examples/rogier/tetra-overconstrained.gcs similarity index 100% rename from solvergui/examples/rogier/tetra-overconstrained.gcs rename to workbench/examples/rogier/tetra-overconstrained.gcs diff --git a/solvergui/examples/rogier/tetra-under.gcs b/workbench/examples/rogier/tetra-under.gcs similarity index 100% rename from solvergui/examples/rogier/tetra-under.gcs rename to workbench/examples/rogier/tetra-under.gcs diff --git a/solvergui/examples/rogier/tetra.gcs b/workbench/examples/rogier/tetra.gcs similarity index 100% rename from solvergui/examples/rogier/tetra.gcs rename to workbench/examples/rogier/tetra.gcs diff --git a/solvergui/examples/rogier/tetra2a.gcs b/workbench/examples/rogier/tetra2a.gcs similarity index 100% rename from solvergui/examples/rogier/tetra2a.gcs rename to workbench/examples/rogier/tetra2a.gcs diff --git a/solvergui/examples/rogier/tetra_ok.gcs b/workbench/examples/rogier/tetra_ok.gcs similarity index 100% rename from solvergui/examples/rogier/tetra_ok.gcs rename to workbench/examples/rogier/tetra_ok.gcs diff --git a/solvergui/examples/rogier/tetrahedron-well.gcs b/workbench/examples/rogier/tetrahedron-well.gcs similarity index 100% rename from solvergui/examples/rogier/tetrahedron-well.gcs rename to workbench/examples/rogier/tetrahedron-well.gcs diff --git a/solvergui/examples/rogier/tetrahedron.gcs b/workbench/examples/rogier/tetrahedron.gcs similarity index 100% rename from solvergui/examples/rogier/tetrahedron.gcs rename to workbench/examples/rogier/tetrahedron.gcs diff --git a/solvergui/examples/rogier/tetrahedron_undercs.gcs b/workbench/examples/rogier/tetrahedron_undercs.gcs similarity index 100% rename from solvergui/examples/rogier/tetrahedron_undercs.gcs rename to workbench/examples/rogier/tetrahedron_undercs.gcs diff --git a/solvergui/examples/rogier/twotetrawell.gcs b/workbench/examples/rogier/twotetrawell.gcs similarity index 100% rename from solvergui/examples/rogier/twotetrawell.gcs rename to workbench/examples/rogier/twotetrawell.gcs diff --git a/solvergui/examples/rogier/well-constrained.gcs b/workbench/examples/rogier/well-constrained.gcs similarity index 100% rename from solvergui/examples/rogier/well-constrained.gcs rename to workbench/examples/rogier/well-constrained.gcs diff --git a/solvergui/examples/rogier/well-constrained2.gcs b/workbench/examples/rogier/well-constrained2.gcs similarity index 100% rename from solvergui/examples/rogier/well-constrained2.gcs rename to workbench/examples/rogier/well-constrained2.gcs diff --git a/solvergui/glViewer.py b/workbench/glViewer.py similarity index 100% rename from solvergui/glViewer.py rename to workbench/glViewer.py diff --git a/solvergui/gui.Doxyfile b/workbench/gui.Doxyfile similarity index 100% rename from solvergui/gui.Doxyfile rename to workbench/gui.Doxyfile diff --git a/solvergui/includes.py b/workbench/includes.py similarity index 100% rename from solvergui/includes.py rename to workbench/includes.py diff --git a/solvergui/main.py b/workbench/main.py similarity index 100% rename from solvergui/main.py rename to workbench/main.py diff --git a/solvergui/panel.py b/workbench/panel.py similarity index 100% rename from solvergui/panel.py rename to workbench/panel.py diff --git a/solvergui/parameters.py b/workbench/parameters.py similarity index 100% rename from solvergui/parameters.py rename to workbench/parameters.py diff --git a/solvergui/pointDialog.py b/workbench/pointDialog.py similarity index 100% rename from solvergui/pointDialog.py rename to workbench/pointDialog.py diff --git a/solvergui/preferencesDlg.py b/workbench/preferencesDlg.py similarity index 100% rename from solvergui/preferencesDlg.py rename to workbench/preferencesDlg.py diff --git a/solvergui/prototypeObjects.py b/workbench/prototypeObjects.py similarity index 100% rename from solvergui/prototypeObjects.py rename to workbench/prototypeObjects.py diff --git a/solvergui/quaternion.py b/workbench/quaternion.py similarity index 100% rename from solvergui/quaternion.py rename to workbench/quaternion.py diff --git a/solvergui/resources/zoomin.png b/workbench/resources/zoomin.png similarity index 100% rename from solvergui/resources/zoomin.png rename to workbench/resources/zoomin.png diff --git a/solvergui/resources/zoomout.png b/workbench/resources/zoomout.png similarity index 100% rename from solvergui/resources/zoomout.png rename to workbench/resources/zoomout.png diff --git a/solvergui/run b/workbench/run similarity index 100% rename from solvergui/run rename to workbench/run diff --git a/solvergui/sceneObjects.py b/workbench/sceneObjects.py similarity index 100% rename from solvergui/sceneObjects.py rename to workbench/sceneObjects.py diff --git a/solvergui/singleton.py b/workbench/singleton.py similarity index 100% rename from solvergui/singleton.py rename to workbench/singleton.py diff --git a/solvergui/solutionView.py b/workbench/solutionView.py similarity index 100% rename from solvergui/solutionView.py rename to workbench/solutionView.py diff --git a/solvergui/solvergui.qrc b/workbench/solvergui.qrc similarity index 100% rename from solvergui/solvergui.qrc rename to workbench/solvergui.qrc diff --git a/solvergui/tools.py b/workbench/tools.py similarity index 100% rename from solvergui/tools.py rename to workbench/tools.py diff --git a/solvergui/tree.py b/workbench/tree.py similarity index 100% rename from solvergui/tree.py rename to workbench/tree.py diff --git a/solvergui/ui/angleeditdialog.ui b/workbench/ui/angleeditdialog.ui similarity index 100% rename from solvergui/ui/angleeditdialog.ui rename to workbench/ui/angleeditdialog.ui diff --git a/solvergui/ui/compositionview.ui b/workbench/ui/compositionview.ui similarity index 100% rename from solvergui/ui/compositionview.ui rename to workbench/ui/compositionview.ui diff --git a/solvergui/ui/constraintdialog.ui b/workbench/ui/constraintdialog.ui similarity index 100% rename from solvergui/ui/constraintdialog.ui rename to workbench/ui/constraintdialog.ui diff --git a/solvergui/ui/distanceeditdialog.ui b/workbench/ui/distanceeditdialog.ui similarity index 100% rename from solvergui/ui/distanceeditdialog.ui rename to workbench/ui/distanceeditdialog.ui diff --git a/solvergui/ui/pointeditdialog.ui b/workbench/ui/pointeditdialog.ui similarity index 100% rename from solvergui/ui/pointeditdialog.ui rename to workbench/ui/pointeditdialog.ui diff --git a/solvergui/ui/preferencesdialog.ui b/workbench/ui/preferencesdialog.ui similarity index 100% rename from solvergui/ui/preferencesdialog.ui rename to workbench/ui/preferencesdialog.ui diff --git a/solvergui/ui/prefsketcher.ui b/workbench/ui/prefsketcher.ui similarity index 100% rename from solvergui/ui/prefsketcher.ui rename to workbench/ui/prefsketcher.ui diff --git a/solvergui/ui/prefviews.ui b/workbench/ui/prefviews.ui similarity index 100% rename from solvergui/ui/prefviews.ui rename to workbench/ui/prefviews.ui diff --git a/solvergui/ui/randomproblemdialog.ui b/workbench/ui/randomproblemdialog.ui similarity index 100% rename from solvergui/ui/randomproblemdialog.ui rename to workbench/ui/randomproblemdialog.ui diff --git a/solvergui/ui/solutionview.ui b/workbench/ui/solutionview.ui similarity index 100% rename from solvergui/ui/solutionview.ui rename to workbench/ui/solutionview.ui diff --git a/solvergui/ui_angleDialog.py b/workbench/ui_angleDialog.py similarity index 100% rename from solvergui/ui_angleDialog.py rename to workbench/ui_angleDialog.py diff --git a/solvergui/ui_compositionView.py b/workbench/ui_compositionView.py similarity index 100% rename from solvergui/ui_compositionView.py rename to workbench/ui_compositionView.py diff --git a/solvergui/ui_constraint.py b/workbench/ui_constraint.py similarity index 100% rename from solvergui/ui_constraint.py rename to workbench/ui_constraint.py diff --git a/solvergui/ui_distanceDialog.py b/workbench/ui_distanceDialog.py similarity index 100% rename from solvergui/ui_distanceDialog.py rename to workbench/ui_distanceDialog.py diff --git a/solvergui/ui_pointDialog.py b/workbench/ui_pointDialog.py similarity index 100% rename from solvergui/ui_pointDialog.py rename to workbench/ui_pointDialog.py diff --git a/solvergui/ui_prefSketcher.py b/workbench/ui_prefSketcher.py similarity index 100% rename from solvergui/ui_prefSketcher.py rename to workbench/ui_prefSketcher.py diff --git a/solvergui/ui_prefViews.py b/workbench/ui_prefViews.py similarity index 100% rename from solvergui/ui_prefViews.py rename to workbench/ui_prefViews.py diff --git a/solvergui/ui_preferencesDlg.py b/workbench/ui_preferencesDlg.py similarity index 100% rename from solvergui/ui_preferencesDlg.py rename to workbench/ui_preferencesDlg.py diff --git a/solvergui/ui_randomProblemDialog.py b/workbench/ui_randomProblemDialog.py similarity index 100% rename from solvergui/ui_randomProblemDialog.py rename to workbench/ui_randomProblemDialog.py diff --git a/solvergui/ui_solutionView.py b/workbench/ui_solutionView.py similarity index 100% rename from solvergui/ui_solutionView.py rename to workbench/ui_solutionView.py diff --git a/solvergui/viewport.py b/workbench/viewport.py similarity index 100% rename from solvergui/viewport.py rename to workbench/viewport.py diff --git a/solvergui/viewportManager.py b/workbench/viewportManager.py similarity index 100% rename from solvergui/viewportManager.py rename to workbench/viewportManager.py