BowlerKernel
BezierEditor.java
Go to the documentation of this file.
1 package com.neuronrobotics.bowlerkernel.Bezier3d;
2 
3 //import com.neuronrobotics.bowlerstudio.BowlerStudio
4 import com.neuronrobotics.bowlerstudio.physics.TransformFactory;
5 import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
6 import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
7 import com.neuronrobotics.sdk.common.Log;
8 import javafx.geometry.Point3D;
9 import javafx.application.Platform;
10 import javafx.event.EventHandler;
11 import javafx.event.EventType;
12 import javafx.scene.input.MouseButton;
13 import javafx.scene.input.MouseEvent;
14 import javafx.scene.paint.Color;
15 import javafx.scene.transform.Affine;
16 import javafx.scene.transform.Rotate;
17 import com.google.gson.Gson;
18 import com.google.gson.GsonBuilder;
19 import com.google.gson.reflect.TypeToken;
20 import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
21 
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.lang.reflect.Type;
27 import java.nio.charset.Charset;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.HashMap;
31 import java.util.List;
32 
33 import org.apache.commons.io.FileUtils;
34 import org.apache.commons.io.IOUtils;
35 import org.eclipse.jgit.api.errors.GitAPIException;
36 import org.eclipse.jgit.api.errors.InvalidRemoteException;
37 import org.eclipse.jgit.api.errors.TransportException;
38 
39 import eu.mihosoft.vrl.v3d.*;
40 import javafx.scene.shape.Line;
41 
42 public class BezierEditor {
43  Type TT_mapStringString = new TypeToken<HashMap<String, HashMap<String, List<Double>>>>() {
44  }.getType();
45  Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
46  File cachejson;
47  TransformNR end = new TransformNR();
48  TransformNR cp1 = new TransformNR();
49  TransformNR cp2 = new TransformNR();
50  TransformNR strt = new TransformNR();
51  private ArrayList<CSG> partsInternal = null;
52  CSG displayPart = new Cylinder(5, 0, 20, 10).toCSG().toZMax().roty(-90);
53 
55  CartesianManipulator cp1Manip;
56  CartesianManipulator cp2Manip;
58  HashMap<String, HashMap<String, List<Double>>> database;
59  boolean updating = false;
60  private String url;
61  private String gitfile;
62  private boolean saving;
63  private ArrayList<BezierEditor> nextBez = new ArrayList<>();
64  private Line cp1Line = new Line();
65  private Line cp2Line = new Line();
66  private Affine cp1LinePose = new Affine();
67  private Affine cp2LinePose = new Affine();
68 
69  public BezierEditor(String URL, String file, int numPoints)
70  throws InvalidRemoteException, TransportException, GitAPIException, IOException {
71  this(ScriptingEngine.fileFromGit(URL, file), numPoints);
72  url = URL;
73  gitfile = file;
74  }
75 
76  public BezierEditor(File data, int numPoints) {
77  cachejson = data;
78  String jsonString = null;
79  boolean loaded = false;
80  try {
81  if (cachejson.exists()) {
82  InputStream inPut = null;
83  inPut = FileUtils.openInputStream(cachejson);
84  jsonString = IOUtils.toString(inPut);
85  database = gson.fromJson(jsonString, TT_mapStringString);
86 
87  List<Double> cp1in = (List<Double>) database.get("bezier").get("control one");
88  List<Double> cp2in = (List<Double>) database.get("bezier").get("control two");
89  List<Double> ep = (List<Double>) database.get("bezier").get("end point");
90  List<Double> st = (List<Double>) database.get("bezier").get("start point");
91  end.setX(ep.get(0));
92  end.setY(ep.get(1));
93  end.setZ(ep.get(2));
94  cp1.setX(cp1in.get(0));
95  cp1.setY(cp1in.get(1));
96  cp1.setZ(cp1in.get(2));
97  cp2.setX(cp2in.get(0));
98  cp2.setY(cp2in.get(1));
99  cp2.setZ(cp2in.get(2));
100 
101  strt.setX(st.get(0));
102  strt.setY(st.get(1));
103  strt.setZ(st.get(2));
104  loaded = true;
105  }
106  } catch (Throwable t) {
107  t.printStackTrace();
108  }
109 
110  if (!loaded) {
111  end.setX(100);
112  end.setY(100);
113  ;
114  end.setZ(100);
115  cp1.setX(50);
116  cp1.setY(-50);
117  cp1.setZ(50);
118  cp2.setX(0);
119  cp2.setY(50);
120  cp2.setZ(-50);
121 
122  database = new HashMap<>();
123  }
124 
125  endManip = new CartesianManipulator(end);
126  cp1Manip = new CartesianManipulator(cp1);
127 
128  cp2Manip = new CartesianManipulator(cp2);
129  endManip.addDependant(cp2Manip);
131 
132  endManip.addSaveListener(() -> {
133  save();
134  });
135  endManip.addEventListener(() -> {
136  update();
137  });
138 
139  cp1Manip.addSaveListener(() -> {
140  save();
141  });
142  cp1Manip.addEventListener(() -> {
143  update();
144  });
145 
146  cp2Manip.addSaveListener(() -> {
147  save();
148  });
149  cp2Manip.addEventListener(() -> {
150  update();
151  });
152  ArrayList<CSG> parts = new ArrayList<>();
153  for (int i = 0; i < numPoints; i++) {
154  CSG part = displayPart.clone();
155  parts.add(part);
156  }
157  setPartsInternal(parts);
158  cp1Line.setStrokeWidth(5);
159  cp2Line.setStrokeWidth(5);
160 
161  cp2Line.getTransforms().addAll(endManip.manipulationMatrix, cp2LinePose);
162  update();
163  save();
164  }
165  public ArrayList<CSG> getCSG() {
166 
167  ArrayList<CSG> back = new ArrayList<>();
168  back.addAll(getEndManip().get());
169  back.addAll(cp1Manip.get());
170  back.addAll(cp2Manip.get());
171  back.addAll(getStartManip().get());
172  back.addAll(getPartsInternal());
173 
174  return back;
175  }
176  public ArrayList<Object> get() {
177 
178  ArrayList<Object> back = new ArrayList<>();
179  back.addAll(getCSG());
180  back.add(cp2Line);
181  back.add(cp1Line);
182 
183  return back;
184  }
185 
186  public void update() {
187  if (updating) {
188  return;
189  }
190  updating = true;
191  ArrayList<Transform> transforms = transforms();
192  for (int i = 0; i < getNumParts(); i++) {
194  Affine partsGetGetManipulator = getPartsInternal().get(i).getManipulator();
195  Platform.runLater(() -> {
196  TransformFactory.nrToAffine(nr, partsGetGetManipulator);
197  });
198  }
199 
200  updateLines(start, cp1Manip, cp1Line, cp1LinePose);
201 
202  TransformNR endVector = updateLines(endManip, cp2Manip, cp2Line, cp2LinePose);
203  if (!endManip.isMoving())
204  for (BezierEditor b : nextBez) {
205  CartesianManipulator m = b.cp1Manip;
207 
208  double cp1XDiff = m.getX() - p.getX();
209  double cp1Ydiff = m.getY() - p.getY();
210  double cp1ZDiff = m.getZ() - p.getZ();
211  double distCP1 = Math.sqrt(Math.pow(cp1XDiff, 2) + Math.pow(cp1Ydiff, 2) + Math.pow(cp1ZDiff, 2));
212  TransformNR vect = endVector.times(new TransformNR(0, distCP1, 0, new RotationNR()));
213  double newX = vect.getX() + p.getX();
214  double newY = vect.getY() + p.getY();
215  double newZ = vect.getZ() + p.getZ();
216  m.set(newX, newY, newZ);
217 
218  }
219 
220  updating = false;
221  }
222 
223  private TransformNR updateLines(CartesianManipulator m, CartesianManipulator p, Line l, Affine poseAF) {
224  double cp1XDiff = m.getX() - p.getX();
225  double cp1Ydiff = m.getY() - p.getY();
226  double cp1ZDiff = m.getZ() - p.getZ();
227  TransformNR vect = new TransformNR(cp1XDiff, cp1Ydiff, cp1ZDiff, new RotationNR());
228 
229  double distCP1 = Math.sqrt(Math.pow(cp1XDiff, 2) + Math.pow(cp1Ydiff, 2) + Math.pow(cp1ZDiff, 2));
230  double xyRot = Math.toDegrees(Math.atan2(cp1Ydiff, cp1XDiff)) - 90;
231 
232  TransformNR az = new TransformNR(0, 0, 0, new RotationNR(0, -xyRot, 0));
233  TransformNR reorented = az.times(vect);
234  // System.out.println("CP1 "+reorented.getX()+" "+reorented.getY()+"
235  // "+reorented.getZ());
236  double xzRot = Math.toDegrees(Math.atan2(reorented.getZ(), reorented.getY()));
237 
238  TransformNR pose = new TransformNR(0, 0, 0, new RotationNR(xzRot, xyRot, 0));
239 
240  Platform.runLater(() -> {
241  TransformFactory.nrToAffine(pose, poseAF);
242 
243  l.setStartX(0);
244  l.setStartY(0);
245  l.setEndY(-distCP1);
246  l.setEndX(0);
247  });
248  return pose;
249  }
250 
251  public void setEnd(double newX, double newY, double newZ) {
252  endManip.set(newX, newY, newZ);
253  save();
254  }
255 
256  public void setStart(double newX, double newY, double newZ) {
257  getStartManip().set(newX, newY, newZ);
258  save();
259 
260  }
261 
262  public void setCP1(double newX, double newY, double newZ) {
263  cp1Manip.set(newX, newY, newZ);
264  save();
265 
266  }
267 
268  public void setCP2(double newX, double newY, double newZ) {
269  cp2Manip.set(newX, newY, newZ);
270  save();
271  }
272 
273  public void setStart(Vector3d point) {
274  this.setStart(point.x, point.y, point.z);
275  }
276 
277  public void setCP1(Vector3d point) {
278  this.setCP1(point.x, point.y, point.z);
279  }
280 
281  public void setCP2(Vector3d point) {
282  this.setCP2(point.x, point.y, point.z);
283  }
284 
285  public void setEnd(Vector3d point) {
286  this.setEnd(point.x, point.y, point.z);
287  }
288 
289  public ArrayList<Transform> transforms() {
290  ArrayList<Transform> tf = Extrude.bezierToTransforms(
291  new Vector3d(cp1Manip.getX() - getStartManip().getX(), cp1Manip.getY() - getStartManip().getY(),
292  cp1Manip.getZ() - getStartManip().getZ()), // Control point one
293  new Vector3d(cp2Manip.getX() - getStartManip().getX(), cp2Manip.getY() - getStartManip().getY(),
294  cp2Manip.getZ() - getStartManip().getZ()), // Control point two
295  new Vector3d(getEndManip().getX() - getStartManip().getX(),
296  getEndManip().getY() - getStartManip().getY(), getEndManip().getZ() - getStartManip().getZ()), // Endpoint
297  getNumParts()// Iterations
298  );
299 
300  for (int i = 0; i < tf.size(); i++) {
301  tf.set(i, tf.get(i).movex(getStartManip().getX()).movey(getStartManip().getY())
302  .movez(getStartManip().getZ()));
303  }
304  return tf;
305  }
306 
307  private int getNumParts() {
308  return getPartsInternal().size();
309  }
310 
311  public void save() {
312  if (saving)
313  return;
314  saving = true;
315  database.clear();
316  HashMap<String, List<Double>> bezData = new HashMap<>();
317 
318  bezData.put("control one", Arrays.asList(cp1Manip.getX(), cp1Manip.getY(), cp1Manip.getZ()));
319  bezData.put("control two", Arrays.asList(cp2Manip.getX(), cp2Manip.getY(), cp2Manip.getZ()));
320  bezData.put("end point", Arrays.asList(getEndManip().getX(), getEndManip().getY(), getEndManip().getZ()));
321  bezData.put("start point",
322  Arrays.asList(getStartManip().getX(), getStartManip().getY(), getStartManip().getZ()));
323  bezData.put("number of points", Arrays.asList((double) getNumParts()));
324  database.put("bezier", bezData);
325 
326  new Thread(() -> {
327  System.out.println("Saving to file " + cachejson.getAbsolutePath());
328  String writeOut = gson.toJson(database, TT_mapStringString);
329  if (url != null) {
330  try {
332  "Saving Bezier");
333  } catch (Exception e) {
334  // TODO Auto-generated catch block
335  e.printStackTrace();
336  }
337  } else {
338  if (!cachejson.exists())
339  try {
340  cachejson.createNewFile();
341  } catch (IOException e) {
342  // TODO Auto-generated catch block
343  e.printStackTrace();
344  }
345  OutputStream out = null;
346  try {
347  out = FileUtils.openOutputStream(cachejson, false);
348  IOUtils.write(writeOut, out);
349  out.close(); // don't swallow close Exception if copy
350  // completes
351  // normally
352  } catch (IOException e) {
353  // TODO Auto-generated catch block
354  e.printStackTrace();
355  } finally {
356  IOUtils.closeQuietly(out);
357  }
358  }
359  saving = false;
360  }).start();
361  for (BezierEditor b : nextBez)
362  b.save();
363  }
364 
366  return endManip;
367  }
368 
369 // private void setEndManip(CartesianManipulator endManip) {
370 // this.endManip = endManip;
371 // }
373  return start;
374  }
375 
377  if (this.start != null)
378  this.start.clearListeners();
379  this.start = start;
380  start.addSaveListener(() -> {
381  save();
382  });
383  start.addEventListener(() -> {
384  update();
385  });
386  start.addDependant(cp1Manip);
387  cp1Line.getTransforms().clear();
388  cp1Line.getTransforms().addAll(start.manipulationMatrix, cp1LinePose);
389 
390  }
391 
393  nextBez.add(b);
395  }
396 
397  public ArrayList<CSG> getPartsInternal() {
398  return partsInternal;
399  }
400 
401  public void setPartsInternal(ArrayList<CSG> partsInternal) {
402  this.partsInternal = partsInternal;
403  for (int i = 0; i < partsInternal.size(); i++) {
404  partsInternal.get(i).setManipulator(new Affine());
405  partsInternal.get(i).setMfg(incoming -> null);
406  partsInternal.get(i).getStorage().set("skeleton", true);
407  }
408  update();
409  }
410 }
TransformNR updateLines(CartesianManipulator m, CartesianManipulator p, Line l, Affine poseAF)
BezierEditor(String URL, String file, int numPoints)
void setCP2(double newX, double newY, double newZ)
void setEnd(double newX, double newY, double newZ)
void setPartsInternal(ArrayList< CSG > partsInternal)
void setStart(double newX, double newY, double newZ)
void setCP1(double newX, double newY, double newZ)
static TransformNR csgToNR(eu.mihosoft.vrl.v3d.Transform csg)
static void pushCodeToGit(String id, String branch, String FileName, String content, String commitMessage)
static File fileFromGit(String remoteURI, String fileInRepo)
CSG roty(Number degreesToRotate)
Definition: CSG.java:560
CSG toZMax(CSG target)
Definition: CSG.java:308
static ArrayList< Transform > bezierToTransforms(Vector3d controlA, Vector3d controlB, Vector3d endPoint, int iterations)
Definition: Extrude.java:419
static Vector3d y(double y)
Definition: Vector3d.java:484
static Vector3d z(double z)
Definition: Vector3d.java:494
static Vector3d x(double x)
Definition: Vector3d.java:474