@@ -357,13 +357,16 @@ def solve(self) -> "Assembly":
357
357
ents = {}
358
358
359
359
i = 0
360
- locked = []
360
+ locked : List [int ] = []
361
+
361
362
for c in self .constraints :
362
363
for name in c .objects :
363
364
if name not in ents :
364
365
ents [name ] = i
365
366
i += 1
366
- if c .kind == "Fixed" or name == self .name :
367
+ if (c .kind == "Fixed" or name == self .name ) and ents [
368
+ name
369
+ ] not in locked :
367
370
locked .append (ents [name ])
368
371
369
372
# Lock the first occuring entity if needed.
@@ -402,15 +405,32 @@ def solve(self) -> "Assembly":
402
405
if not constraints :
403
406
raise ValueError ("At least one constraint required" )
404
407
408
+ # check if at least two entities are present
409
+ if len (ents ) < 2 :
410
+ raise ValueError ("At least two entities need to be constrained" )
411
+
405
412
# instantiate the solver
406
- solver = ConstraintSolver (locs , constraints , locked = locked )
413
+ scale = self .toCompound ().BoundingBox ().DiagonalLength
414
+ solver = ConstraintSolver (locs , constraints , locked = locked , scale = scale )
407
415
408
416
# solve
409
417
locs_new , self ._solve_result = solver .solve ()
410
418
411
419
# update positions
420
+
421
+ # find the inverse root loc
422
+ loc_root_inv = Location ()
423
+
424
+ if self .obj :
425
+ for loc_new , n in zip (locs_new , ents ):
426
+ if n == self .name :
427
+ loc_root_inv = loc_new .inverse
428
+ break
429
+
430
+ # update the positions
412
431
for loc_new , n in zip (locs_new , ents ):
413
- self .objects [n ].loc = loc_new
432
+ if n != self .name :
433
+ self .objects [n ].loc = loc_root_inv * loc_new
414
434
415
435
return self
416
436
0 commit comments