Solve current constraints and update edge positions.
(self: T)
| 1000 | return self |
| 1001 | |
| 1002 | def solve(self: T) -> T: |
| 1003 | """ |
| 1004 | Solve current constraints and update edge positions. |
| 1005 | """ |
| 1006 | |
| 1007 | entities = [] # list with all degrees of freedom |
| 1008 | e2i = {} # mapping from tags to indices of entities |
| 1009 | geoms = [] # geometry types |
| 1010 | |
| 1011 | # fill entities, e2i and geoms |
| 1012 | for i, (k, v) in enumerate( |
| 1013 | filter(lambda kv: isinstance(kv[1][0], Edge), self._tags.items()) |
| 1014 | ): |
| 1015 | |
| 1016 | v0 = tcast(Edge, v[0]) |
| 1017 | |
| 1018 | # dispatch on geom type |
| 1019 | if v0.geomType() == "LINE": |
| 1020 | p1 = v0.startPoint() |
| 1021 | p2 = v0.endPoint() |
| 1022 | ent: DOF = (p1.x, p1.y, p2.x, p2.y) |
| 1023 | |
| 1024 | elif v0.geomType() == "CIRCLE": |
| 1025 | p = v0.arcCenter() |
| 1026 | p1 = v0.startPoint() - p |
| 1027 | p2 = v0.endPoint() - p |
| 1028 | pm = v0.positionAt(0.5) - p |
| 1029 | |
| 1030 | a1 = Vector(0, 1).getSignedAngle(p1) |
| 1031 | a2 = p1.getSignedAngle(p2) |
| 1032 | a3 = p1.getSignedAngle(pm) |
| 1033 | if a3 > 0 and a2 < 0: |
| 1034 | a2 += 2 * pi |
| 1035 | elif a3 < 0 and a2 > 0: |
| 1036 | a2 -= 2 * pi |
| 1037 | radius = v0.radius() |
| 1038 | ent = (p.x, p.y, radius, a1, a2) |
| 1039 | |
| 1040 | else: |
| 1041 | continue |
| 1042 | |
| 1043 | entities.append(ent) |
| 1044 | e2i[k] = i |
| 1045 | geoms.append(v0.geomType()) |
| 1046 | |
| 1047 | # build the POD constraint list |
| 1048 | constraints = [] |
| 1049 | for c in self._constraints: |
| 1050 | ix = (e2i[c.tags[0]], e2i[c.tags[1]] if len(c.tags) == 2 else None) |
| 1051 | constraints.append((ix, c.kind, c.param)) |
| 1052 | |
| 1053 | # optimize |
| 1054 | solver = SketchConstraintSolver(entities, constraints, geoms) |
| 1055 | res, self._solve_status = solver.solve() |
| 1056 | self._solve_status["x"] = res |
| 1057 | |
| 1058 | # translate back the solution - update edges |
| 1059 | for g, (k, i) in zip(geoms, e2i.items()): |