Skip to content

Commit a425e7d

Browse files
committed
Uniform scaling for corner drags
Uniform scaling for corner drags
1 parent ac7f61d commit a425e7d

File tree

1 file changed

+214
-77
lines changed

1 file changed

+214
-77
lines changed

src/main/java/com/commonwealthrobotics/controls/ResizeSessionManager.java

Lines changed: 214 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class ResizeSessionManager {
3636
private boolean locked;
3737
private boolean resizeAllowed;
3838
private boolean moveLock;
39+
private Bounds originalBounds = null;
3940

4041
public ResizeSessionManager(BowlerStudio3dEngine engine, Affine selection, Runnable updateLines, ActiveProject ap,
4142
SelectionSession s, Affine workplaneOffset, MoveUpArrow up) {
@@ -62,120 +63,255 @@ public ResizeSessionManager(BowlerStudio3dEngine engine, Affine selection, Runna
6263
updateLines, onReset);
6364

6465
rightFront.manipulator.addEventListener(ev -> {
65-
if (scalingFlag)
66-
return;
67-
68-
scalingFlag = false;
6966
if (beingUpdated == null)
7067
beingUpdated = rightFront;
71-
if (beingUpdated != rightFront) {
72-
// com.neuronrobotics.sdk.common.Log.error("Motion from "+beingUpdated+"
73-
// rejected by "+rightFront);
68+
if (beingUpdated != rightFront)
69+
return;
70+
if (scalingFlag) { // cancel one recursive call
71+
scalingFlag = false;
7472
return;
7573
}
76-
double x = rightRear.manipulator.getCurrentPose().getX();
77-
double y = rightFront.manipulator.getCurrentPose().getY();
78-
double z = rightRear.manipulator.getCurrentPose().getZ();
79-
// com.neuronrobotics.sdk.common.Log.error("rightRear Move x" + x + " y" + y + "
80-
// z" + z);
81-
rightRear.manipulator.setInReferenceFrame(x, y, z);
82-
x = rightFront.manipulator.getCurrentPose().getX();
83-
y = leftFront.manipulator.getCurrentPose().getY();
84-
leftFront.manipulator.setInReferenceFrame(x, y, z);
74+
75+
// Uniform scaling with shift key
76+
if (ev != null && ev.isShiftDown()) {
77+
if (originalBounds == null)
78+
originalBounds = getBounds();
79+
80+
double original_x = originalBounds.getTotalX();
81+
double original_y = originalBounds.getTotalY();
82+
double original_diagonal = Math.hypot(original_x, original_y);
83+
84+
// Mouse offset from manipulator
85+
double mouseX = rightFront.getCurrentInReferenceFrame().getX() - originalBounds.getMaxX(); // Front
86+
double mouseY = - rightFront.getCurrentInReferenceFrame().getY() + originalBounds.getMinY(); // Right
87+
double scale = (mouseX * original_x + mouseY * original_y) / (original_diagonal * original_diagonal);
88+
89+
double rawNewX = original_x * (1.0 + scale); // Snap X-dimension to grid
90+
double gridNewX = Math.round(rawNewX / size) * size;
91+
double difference_x = Math.abs(rawNewX - gridNewX);
92+
93+
double rawNewY = original_y * (1.0 + scale); // Snap Y-dimension to grid
94+
double gridNewY = Math.round(rawNewY / size) * size;
95+
double difference_y = Math.abs(rawNewY - gridNewY);
96+
double gridScale;
97+
98+
if (difference_x < difference_y)
99+
gridScale = (gridNewX / original_x) - 1.0;
100+
else
101+
gridScale = (gridNewY / original_y) - 1.0;
102+
103+
scalingFlag = true;
104+
rightFront.manipulator.setInReferenceFrame(original_x * gridScale, -original_y * gridScale, 0);
105+
rightRear.manipulator.setInReferenceFrame (0, -original_y * gridScale, 0);
106+
leftFront.manipulator.setInReferenceFrame (original_x * gridScale, 0 , 0);
107+
topCenter.setInReferenceFrame (0, 0, originalBounds.getMinZ() + originalBounds.getTotalZ() * (gridScale + 1));
108+
109+
} else {
110+
// Unconstraint resizing path
111+
double x = rightRear.manipulator.getCurrentPose().getX();
112+
double y = rightFront.manipulator.getCurrentPose().getY();
113+
double z = rightRear.manipulator.getCurrentPose().getZ();
114+
rightRear.manipulator.setInReferenceFrame(x, y, z);
115+
x = rightFront.manipulator.getCurrentPose().getX();
116+
y = leftFront.manipulator.getCurrentPose().getY();
117+
leftFront.manipulator.setInReferenceFrame(x, y, z);
118+
}
119+
85120
BowlerStudio.runLater(() -> update());
86-
// com.neuronrobotics.sdk.common.Log.error("rightFront");
87121
});
88-
rightRear.manipulator.addEventListener(ev -> {
89-
if (scalingFlag)
90-
return;
91-
92-
scalingFlag = false;
93122

123+
rightRear.manipulator.addEventListener(ev -> {
94124
if (beingUpdated == null)
95125
beingUpdated = rightRear;
96-
if (beingUpdated != rightRear) {
97-
// com.neuronrobotics.sdk.common.Log.error("Motion from "+beingUpdated+"
98-
// rejected by "+rightRear);
126+
if (beingUpdated != rightRear)
127+
return;
128+
if (scalingFlag) {
129+
scalingFlag = false;
99130
return;
100131
}
101-
double x = rightFront.manipulator.getCurrentPose().getX();
102-
double y = rightRear.manipulator.getCurrentPose().getY();
103-
double z = rightFront.manipulator.getCurrentPose().getZ();
104-
rightFront.manipulator.setInReferenceFrame(x, y, z);
105-
x = rightRear.manipulator.getCurrentPose().getX();
106-
y = leftRear.manipulator.getCurrentPose().getY();
107-
leftRear.manipulator.setInReferenceFrame(x, y, z);
132+
133+
if (ev != null && ev.isShiftDown()) {
134+
// Uniform scaling
135+
if (originalBounds == null)
136+
originalBounds = getBounds();
137+
138+
double original_x = originalBounds.getTotalX();
139+
double original_y = originalBounds.getTotalY();
140+
double original_diagonal = Math.hypot(original_x, original_y);
141+
142+
// Mouse offset from manipulator
143+
double mouseX = -rightRear.getCurrentInReferenceFrame().getX() + originalBounds.getMinX(); // Rear
144+
double mouseY = -rightRear.getCurrentInReferenceFrame().getY() + originalBounds.getMinY(); // Right
145+
double scale = (mouseX * original_x + mouseY * original_y) / (original_diagonal * original_diagonal);
146+
147+
double rawNewX = original_x * (1.0 + scale); // Snap X-dimension to grid
148+
double gridNewX = Math.round(rawNewX / size) * size;
149+
double difference_x = Math.abs(rawNewX - gridNewX);
150+
151+
double rawNewY = original_y * (1.0 + scale); // Snap Y-dimension to grid
152+
double gridNewY = Math.round(rawNewY / size) * size;
153+
double difference_y = Math.abs(rawNewY - gridNewY);
154+
double gridScale;
155+
156+
if (difference_x < difference_y)
157+
gridScale = (gridNewX / original_x) - 1.0;
158+
else
159+
gridScale = (gridNewY / original_y) - 1.0;
160+
161+
scalingFlag = true; // Set to true to prevent recursive call
162+
rightRear.manipulator.setInReferenceFrame(-original_x * gridScale, -original_y * gridScale, 0);
163+
rightFront.manipulator.setInReferenceFrame(0, -original_y * gridScale, 0);
164+
leftRear.manipulator.setInReferenceFrame (-original_x * gridScale, 0 , 0);
165+
topCenter.setInReferenceFrame (0, 0, originalBounds.getMinZ() + originalBounds.getTotalZ() * (gridScale + 1));
166+
} else {
167+
double x = rightFront.manipulator.getCurrentPose().getX();
168+
double y = rightRear.manipulator.getCurrentPose().getY();
169+
double z = rightFront.manipulator.getCurrentPose().getZ();
170+
rightFront.manipulator.setInReferenceFrame(x, y, z);
171+
x = rightRear.manipulator.getCurrentPose().getX();
172+
y = leftRear.manipulator.getCurrentPose().getY();
173+
leftRear.manipulator.setInReferenceFrame(x, y, z);
174+
}
175+
108176
BowlerStudio.runLater(() -> update());
109-
// com.neuronrobotics.sdk.common.Log.error("rightRear");
110177
});
111-
leftFront.manipulator.addEventListener(ev -> {
112-
if (scalingFlag)
113-
return;
114-
115-
scalingFlag = false;
116178

179+
leftFront.manipulator.addEventListener(ev -> {
117180
if (beingUpdated == null)
118181
beingUpdated = leftFront;
119-
if (beingUpdated != leftFront) {
120-
// com.neuronrobotics.sdk.common.Log.error("Motion from "+beingUpdated+"
121-
// rejected by "+leftFront);
182+
if (beingUpdated != leftFront)
122183
return;
184+
if (scalingFlag) {
185+
scalingFlag = false;
186+
return;
187+
}
188+
189+
if (ev != null && ev.isShiftDown()) {
190+
// Uniform scaling
191+
if (originalBounds == null)
192+
originalBounds = getBounds();
193+
194+
double original_x = originalBounds.getTotalX();
195+
double original_y = originalBounds.getTotalY();
196+
double original_diagonal = Math.hypot(original_x, original_y);
197+
198+
// Mouse offset from manipulator
199+
double mouseX = leftFront.getCurrentInReferenceFrame().getX() - originalBounds.getMaxX(); // Front
200+
double mouseY = leftFront.getCurrentInReferenceFrame().getY() - originalBounds.getMaxY(); // Left
201+
double scale = (mouseX * original_x + mouseY * original_y) / (original_diagonal * original_diagonal);
202+
203+
double rawNewX = original_x * (1.0 + scale); // Snap X-dimension to grid
204+
double gridNewX = Math.round(rawNewX / size) * size;
205+
double difference_x = Math.abs(rawNewX - gridNewX);
206+
207+
double rawNewY = original_y * (1.0 + scale); // Snap Y-dimension to grid
208+
double gridNewY = Math.round(rawNewY / size) * size;
209+
double difference_y = Math.abs(rawNewY - gridNewY);
210+
double gridScale;
211+
212+
if (difference_x < difference_y)
213+
gridScale = (gridNewX / original_x) - 1.0;
214+
else
215+
gridScale = (gridNewY / original_y) - 1.0;
216+
217+
scalingFlag = true; // Set to true to prevent recursive call
218+
leftFront.manipulator.setInReferenceFrame (original_x * gridScale, original_y * gridScale, 0);
219+
rightFront.manipulator.setInReferenceFrame(original_x * gridScale, 0, 0);
220+
leftRear.manipulator.setInReferenceFrame (0, original_y * gridScale, 0);
221+
topCenter.setInReferenceFrame(0, 0, originalBounds.getMinZ() + originalBounds.getTotalZ() * (gridScale + 1));
222+
} else {
223+
double x = leftRear.manipulator.getCurrentPose().getX();
224+
double y = leftFront.manipulator.getCurrentPose().getY();
225+
double z = leftFront.manipulator.getCurrentPose().getZ();
226+
leftRear.manipulator.setInReferenceFrame(x, y, z);
227+
x = leftFront.manipulator.getCurrentPose().getX();
228+
y = rightFront.manipulator.getCurrentPose().getY();
229+
rightFront.manipulator.setInReferenceFrame(x, y, z);
123230
}
124-
double x = leftRear.manipulator.getCurrentPose().getX();
125-
double y = leftFront.manipulator.getCurrentPose().getY();
126-
double z = leftFront.manipulator.getCurrentPose().getZ();
127-
leftRear.manipulator.setInReferenceFrame(x, y, z);
128-
x = leftFront.manipulator.getCurrentPose().getX();
129-
y = rightFront.manipulator.getCurrentPose().getY();
130-
rightFront.manipulator.setInReferenceFrame(x, y, z);
131-
BowlerStudio.runLater(() -> update()); // com.neuronrobotics.sdk.common.Log.error("leftFront");
231+
232+
BowlerStudio.runLater(() -> update());
132233
});
133-
leftRear.manipulator.addEventListener(ev -> {
134-
if (scalingFlag)
135-
return;
136-
scalingFlag = false;
137234

235+
leftRear.manipulator.addEventListener(ev -> {
138236
if (beingUpdated == null)
139237
beingUpdated = leftRear;
140-
if (beingUpdated != leftRear) {
141-
// com.neuronrobotics.sdk.common.Log.error("Motion from "+beingUpdated+"
142-
// rejected by "+leftRear);
238+
if (beingUpdated != leftRear)
143239
return;
240+
if (scalingFlag) {
241+
scalingFlag = false;
242+
return;
243+
}
244+
245+
if (ev != null && ev.isShiftDown()) {
246+
// Uniform scaling
247+
if (originalBounds == null)
248+
originalBounds = getBounds();
249+
250+
double original_x = originalBounds.getTotalX();
251+
double original_y = originalBounds.getTotalY();
252+
double original_diagonal = Math.hypot(original_x, original_y);
253+
254+
// Mouse offset from manipulator
255+
double mouseX = -leftRear.getCurrentInReferenceFrame().getX() + originalBounds.getMinX(); // Rear
256+
double mouseY = leftRear.getCurrentInReferenceFrame().getY() - originalBounds.getMaxY(); // Left
257+
double scale = (mouseX * original_x + mouseY * original_y) / (original_diagonal * original_diagonal);
258+
259+
double rawNewX = original_x * (1.0 + scale); // Snap X-dimension to grid
260+
double gridNewX = Math.round(rawNewX / size) * size;
261+
double difference_x = Math.abs(rawNewX - gridNewX);
262+
263+
double rawNewY = original_y * (1.0 + scale); // Snap Y-dimension to grid
264+
double gridNewY = Math.round(rawNewY / size) * size;
265+
double difference_y = Math.abs(rawNewY - gridNewY);
266+
double gridScale;
267+
268+
if (difference_x < difference_y)
269+
gridScale = (gridNewX / original_x) - 1.0;
270+
else
271+
gridScale = (gridNewY / original_y) - 1.0;
272+
273+
scalingFlag = true; // Set to true to prevent recursive call
274+
leftRear.manipulator.setInReferenceFrame (-original_x * gridScale, original_y * gridScale, 0);
275+
leftFront.manipulator.setInReferenceFrame(0, original_y * gridScale, 0);
276+
rightRear.manipulator.setInReferenceFrame(-original_x * gridScale, 0 , 0);
277+
topCenter.setInReferenceFrame(0, 0, originalBounds.getMinZ() + originalBounds.getTotalZ() * (gridScale + 1));
278+
} else {
279+
double x = leftFront.manipulator.getCurrentPose().getX();
280+
double y = leftRear.manipulator.getCurrentPose().getY();
281+
double z = leftRear.manipulator.getCurrentPose().getZ();
282+
leftFront.manipulator.setInReferenceFrame(x, y, z);
283+
x = leftRear.manipulator.getCurrentPose().getX();
284+
y = rightRear.manipulator.getCurrentPose().getY();
285+
rightRear.manipulator.setInReferenceFrame(x, y, z);
144286
}
145287

146-
double x = leftFront.manipulator.getCurrentPose().getX();
147-
double y = leftRear.manipulator.getCurrentPose().getY();
148-
double z = leftRear.manipulator.getCurrentPose().getZ();
149-
leftFront.manipulator.setInReferenceFrame(x, y, z);
150-
x = leftRear.manipulator.getCurrentPose().getX();
151-
y = rightRear.manipulator.getCurrentPose().getY();
152-
rightRear.manipulator.setInReferenceFrame(x, y, z);
153-
BowlerStudio.runLater(() -> update()); // com.neuronrobotics.sdk.common.Log.error("leftRear");
288+
BowlerStudio.runLater(() -> update());
154289
});
155-
topCenter.manipulator.addEventListener(ev -> {
156-
scalingFlag = false;
157290

291+
topCenter.manipulator.addEventListener(ev -> {
158292
if (beingUpdated == null)
159293
beingUpdated = topCenter;
160-
if (beingUpdated != topCenter) {
161-
// com.neuronrobotics.sdk.common.Log.error("Motion from "+beingUpdated+"
162-
// rejected by "+topCenter);
294+
if (beingUpdated != topCenter)
295+
return;
296+
if (scalingFlag) {
297+
scalingFlag = false;
163298
return;
164299
}
300+
165301
if (ev != null)
166302
if (ev.isShiftDown()) {
167303
TransformNR tcC = topCenter.getCurrentInReferenceFrame();
168304
uniformScalingZ(tcC);
169-
// com.neuronrobotics.sdk.common.Log.debug("RE-Scaling whole object! "+scale);
170305
}
171306
BowlerStudio.runLater(() -> update());
172-
173-
// com.neuronrobotics.sdk.common.Log.error("topCenter");
174307
});
308+
175309
controls = Arrays.asList(topCenter, rightFront, rightRear, leftFront, leftRear);
176310
for (ResizingHandle c : controls) {
177311
c.manipulator.setFrameOfReference(() -> ap.get().getWorkplane());
178312
c.manipulator.addSaveListener(() -> {
313+
if (beingUpdated != c)
314+
return;
179315
try {
180316
Thread.sleep(32);
181317
} catch (InterruptedException e) {
@@ -196,7 +332,6 @@ public ResizeSessionManager(BowlerStudio3dEngine engine, Affine selection, Runna
196332
for (ResizingHandle ctrl : controls) {
197333
ctrl.manipulator.set(0, 0, 0);
198334
}
199-
beingUpdated = null;
200335
// if (Math.abs(lfC.getZ() - rrC.getZ()) > 0.00001) {
201336
// throw new RuntimeException("The control points of the corners must be at the same Z value \n"
202337
// + lfC.toSimpleString() + "\n" + rrC.toSimpleString());
@@ -214,6 +349,7 @@ public ResizeSessionManager(BowlerStudio3dEngine engine, Affine selection, Runna
214349
com.neuronrobotics.sdk.common.Log.error(e);
215350
}
216351
}
352+
beingUpdated = null;
217353
BowlerStudio.runLater(() -> threeDTarget());
218354
});
219355
}
@@ -227,7 +363,6 @@ public void setResizeAllowed(boolean resizeAllowed, boolean moveLock) {
227363
}
228364

229365
private void uniformScalingZ(TransformNR tcC) {
230-
scalingFlag = true;
231366
double startZ = bounds.getTotalZ();
232367
double startX = bounds.getTotalX();
233368
double startY = bounds.getTotalY();
@@ -250,10 +385,11 @@ private void uniformScalingZ(TransformNR tcC) {
250385
double newY = -newYComp;
251386
double newX2 = +newXComp;
252387
double newY2 = +newYComp;
388+
scalingFlag = true;
253389
rightRear.manipulator.setInReferenceFrame(newX, newY, z);
254-
leftFront.manipulator.setInReferenceFrame(newX2, newY2, z);
255-
rightFront.manipulator.setInReferenceFrame(newX2, newY, z);
256-
leftRear.manipulator.setInReferenceFrame(newX, newY2, z);
390+
leftFront.manipulator.setInReferenceFrame(newX2, newY2, z);
391+
rightFront.manipulator.setInReferenceFrame(newX2, newY, z);
392+
leftRear.manipulator.setInReferenceFrame(newX, newY2, z);
257393
}
258394

259395
private void update() {
@@ -346,6 +482,7 @@ public void setSnapGrid(double size) {
346482
}
347483

348484
public void resetSelected() {
485+
originalBounds = null; // reset var that exists to help maintain aspect ratios
349486
for (ResizingHandle c : controls) {
350487
c.resetSelected();
351488
}

0 commit comments

Comments
 (0)