JavaCAD
Extrude.java
Go to the documentation of this file.
1 
34 package eu.mihosoft.vrl.v3d;
35 
36 import java.util.ArrayList;
37 import com.piro.bezier.BezierPath;
38 import eu.mihosoft.vrl.v3d.Transform;
39 import eu.mihosoft.vrl.v3d.svg.*;
40 import java.util.Arrays;
41 import java.util.Collections;
42 import java.util.List;
43 
44 //import javax.vecmath.Vector3d;
45 
46 import eu.mihosoft.vrl.v3d.ext.org.poly2tri.PolygonUtil;
47 import eu.mihosoft.vrl.v3d.ext.quickhull3d.HullUtil;
48 
49 // TODO: Auto-generated Javadoc
55 public class Extrude {
56  private static IExtrusion extrusionEngine = new IExtrusion() {
66  public CSG points(Vector3d dir, List<Vector3d> points) {
67 
68  List<Vector3d> newList = new ArrayList<>(points);
69 
70  return extrude(dir, Polygon.fromPoints(toCCW(newList)));
71  }
72 
80  public CSG extrude(Vector3d dir, Polygon polygon1) {
81 
82  return monotoneExtrude(dir, polygon1);
83  }
84 
85  private CSG monotoneExtrude(Vector3d dir, Polygon polygon1) {
86  List<Polygon> newPolygons = new ArrayList<>();
87  CSG extrude;
88  //polygon1=polygon1.flipped();
89  newPolygons.addAll(PolygonUtil.concaveToConvex(polygon1.flipped()));
90  Polygon polygon2 = polygon1.translated(dir);
91 
92  int numvertices = polygon1.vertices.size();
93  for (int i = 0; i < numvertices; i++) {
94 
95  int nexti = (i + 1) % numvertices;
96 
97  Vector3d bottomV1 = polygon1.vertices.get(i).pos;
98  Vector3d topV1 = polygon2.vertices.get(i).pos;
99  Vector3d bottomV2 = polygon1.vertices.get(nexti).pos;
100  Vector3d topV2 = polygon2.vertices.get(nexti).pos;
101 
102  List<Vector3d> pPoints = Arrays.asList(bottomV2, topV2, topV1, bottomV1);
103 
104  newPolygons.add(Polygon.fromPoints(pPoints, polygon1.getStorage()));
105 
106  }
107 
108  polygon2 = polygon2.flipped();
109  List<Polygon> topPolygons = PolygonUtil.concaveToConvex(polygon2.flipped());
110 
111  newPolygons.addAll(topPolygons);
112  extrude = CSG.fromPolygons(newPolygons);
113 
114  return extrude;
115  }
116 
117  @Override
118  public CSG extrude(Vector3d dir, List<Vector3d> points) {
119  return points(dir, points);
120  }
121  };
122 
126  private Extrude() {
127  throw new AssertionError("Don't instantiate me!", null);
128  }
129 
130  public static CSG polygons(Polygon polygon1, Number zDistance) {
131  return polygons(polygon1, polygon1.transformed(new Transform().movez(zDistance)));
132  }
133 
134  public static CSG polygons(Polygon polygon1, Polygon polygon2) {
135  // if(!isCCW(polygon1)) {
136  // polygon1=Polygon.fromPoints(toCCW(polygon1.getPoints()));
137  // }
138  // if(!isCCW(polygon2)) {
139  // polygon2=Polygon.fromPoints(toCCW(polygon2.getPoints()));
140  // }
141 
142  List<Polygon> newPolygons = new ArrayList<>();
143  CSG extrude;
144  newPolygons.addAll(PolygonUtil.concaveToConvex(polygon1.flipped()));
145  if (polygon1.vertices.size() != polygon2.vertices.size()) {
146  throw new RuntimeException("These polygons do not match");
147  }
148 
149  int numvertices = polygon1.vertices.size();
150  for (int i = 0; i < numvertices; i++) {
151 
152  int nexti = (i + 1) % numvertices;
153 
154  Vector3d bottomV1 = polygon1.vertices.get(i).pos;
155  Vector3d topV1 = polygon2.vertices.get(i).pos;
156  Vector3d bottomV2 = polygon1.vertices.get(nexti).pos;
157  Vector3d topV2 = polygon2.vertices.get(nexti).pos;
158 
159  List<Vector3d> pPoints = Arrays.asList(bottomV2, topV2, topV1, bottomV1);
160 
161  newPolygons.add(Polygon.fromPoints(pPoints, polygon1.getStorage()));
162 
163  }
164 
165  polygon2 = polygon2.flipped();
166  List<Polygon> topPolygons = PolygonUtil.concaveToConvex(polygon2.flipped());
167 
168  newPolygons.addAll(topPolygons);
169  extrude = CSG.fromPolygons(newPolygons);
170 
171  return extrude;
172  }
173 
174  public static ArrayList<CSG> polygons(eu.mihosoft.vrl.v3d.Polygon polygon1, ArrayList<Transform> transforms) {
175  if (transforms.size() == 1)
176  transforms.add(0, new Transform());
177  polygon1 = Polygon.fromPoints(toCCW(polygon1.getPoints()));
178  if (transforms.size() < 2) {
179  transforms.add(0, new Transform());
180  }
181  ArrayList<CSG> parts = new ArrayList<>();
182  Transform transform = new Transform();
183  // transform.rotY(90);
184  for (int i = 0; i < transforms.size() - 1; i++) {
185  CSG tmp = polygons(polygon1.transformed(transform).transformed(transforms.get(i)),
186  polygon1.transformed(transform).transformed(transforms.get(i + 1)));
187  parts.add(tmp);
188  }
189  return parts;
190 
191  }
192 
193  public static ArrayList<CSG> polygons(eu.mihosoft.vrl.v3d.Polygon polygon1, Transform... transformparts) {
194 
195  return polygons(polygon1, (ArrayList<Transform>) Arrays.asList(transformparts));
196 
197  }
198 
199  public static CSG points(Vector3d dir, List<Vector3d> points) {
200 
201  return getExtrusionEngine().extrude(dir, points);
202  }
203 
213  public static CSG points(Vector3d dir, Vector3d... points) {
214 
215  return points(dir, Arrays.asList(points));
216  }
217 
224  public static List<Vector3d> toCCW(List<Vector3d> points) {
225 
226  List<Vector3d> result = new ArrayList<>(points);
227 
228  if (!isCCW(Polygon.fromPoints(result))) {
229  Collections.reverse(result);
230  }
231 
232  return result;
233  }
234 
241  static List<Vector3d> toCW(List<Vector3d> points) {
242 
243  List<Vector3d> result = new ArrayList<>(points);
244 
245  if (isCCW(Polygon.fromPoints(result))) {
246  Collections.reverse(result);
247  }
248 
249  return result;
250  }
251 
258  public static boolean isCCW(Polygon polygon) {
259 
260  // thanks to Sepp Reiter for explaining me the algorithm!
261 
262  if (polygon.vertices.size() < 3) {
263  throw new IllegalArgumentException("Only polygons with at least 3 vertices are supported!");
264  }
265 
266  // search highest left vertex
267  int highestLeftVertexIndex = 0;
268  Vertex highestLeftVertex = polygon.vertices.get(0);
269  for (int i = 0; i < polygon.vertices.size(); i++) {
270  Vertex v = polygon.vertices.get(i);
271 
272  if (v.pos.y > highestLeftVertex.pos.y) {
273  highestLeftVertex = v;
274  highestLeftVertexIndex = i;
275  } else if (v.pos.y == highestLeftVertex.pos.y && v.pos.x < highestLeftVertex.pos.x) {
276  highestLeftVertex = v;
277  highestLeftVertexIndex = i;
278  }
279  }
280 
281  // determine next and previous vertex indices
282  int nextVertexIndex = (highestLeftVertexIndex + 1) % polygon.vertices.size();
283  int prevVertexIndex = highestLeftVertexIndex - 1;
284  if (prevVertexIndex < 0) {
285  prevVertexIndex = polygon.vertices.size() - 1;
286  }
287  Vertex nextVertex = polygon.vertices.get(nextVertexIndex);
288  Vertex prevVertex = polygon.vertices.get(prevVertexIndex);
289 
290  // edge 1
291  double a1 = normalizedX(highestLeftVertex.pos, nextVertex.pos);
292 
293  // edge 2
294  double a2 = normalizedX(highestLeftVertex.pos, prevVertex.pos);
295 
296  // select vertex with lowest x value
297  int selectedVIndex;
298 
299  if (a2 > a1) {
300  selectedVIndex = nextVertexIndex;
301  } else {
302  selectedVIndex = prevVertexIndex;
303  }
304 
305  if (selectedVIndex == 0 && highestLeftVertexIndex == polygon.vertices.size() - 1) {
306  selectedVIndex = polygon.vertices.size();
307  }
308 
309  if (highestLeftVertexIndex == 0 && selectedVIndex == polygon.vertices.size() - 1) {
310  highestLeftVertexIndex = polygon.vertices.size();
311  }
312 
313  // indicates whether edge points from highestLeftVertexIndex towards
314  // the sel index (ccw)
315  return selectedVIndex > highestLeftVertexIndex;
316 
317  }
318 
326  private static double normalizedX(Vector3d v1, Vector3d v2) {
327  Vector3d v2MinusV1 = v2.minus(v1);
328 
329  return v2MinusV1.dividedBy(v2MinusV1.magnitude()).times(Vector3d.X_ONE).x;
330  }
331 
332  public static IExtrusion getExtrusionEngine() {
333  return extrusionEngine;
334  }
335 
338  }
339 
340  public static CSG byPath(List<List<Vector3d>> points, double height) {
341 
342  return byPath(points, height, 200);
343 
344  }
345 
346  public static CSG byPath(List<List<Vector3d>> points, double height, int resolution) {
347  ArrayList<Transform> trPath = pathToTransforms(points, resolution);
348  ArrayList<Vector3d> finalPath = new ArrayList<>();
349  for (Transform tr : trPath) {
350  javax.vecmath.Vector3d t1 = new javax.vecmath.Vector3d();
351  tr.getInternalMatrix().get(t1);
352  Vector3d finalPoint = new Vector3d(t1.x, t1.y, 0);
353  finalPath.add(finalPoint);
354  }
355  // showEdges(finalPath,(double)0.0,javafx.scene.paint.Color.RED)
356  // println "Path size = " +finalPath.size()
357  // List<Polygon> p = Polygon.fromConcavePoints(finalPath)
358  // for(Polygon pl:p)
359  // BowlerStudioController.getBowlerStudio()addObject(pl,null)
360  // return new Cube(height).toCSG()
361  return Extrude.points(new Vector3d(0, 0, height), finalPath);
362  }
363 
364  public static ArrayList<Transform> pathToTransforms(List<List<Vector3d>> points, int resolution) {
365 
366  Vector3d start = points.get(0).get(0);
367  String pathStringA = "M " + start.x + "," + start.y;
368  String pathStringB = pathStringA;
369 
370  for (List<Vector3d> sections : points) {
371  if (sections.size() == 4) {
372  Vector3d controlA = sections.get(1);
373  Vector3d controlB = sections.get(2);
374  Vector3d endPoint = sections.get(3);
375  /*
376  * ArrayList<Double> controlA = (ArrayList<Double>)
377  * Arrays.asList(sections.get(1).x - start.get(0), sections.get(1).y -
378  * start.get(1), sections.get(1).z - start.get(2));
379  *
380  * ArrayList<Double> controlB = (ArrayList<Double>)
381  * Arrays.asList(sections.get(2).x - start.get(0), sections.get(2).y -
382  * start.get(1), sections.get(2).z - start.get(2)); ; ArrayList<Double> endPoint
383  * = (ArrayList<Double>) Arrays.asList(sections.get(3).x - start.get(0),
384  * sections.get(3).y - start.get(1), sections.get(3).z - start.get(2)); ;
385  */
386 
387  pathStringA += ("C " + controlA.x + "," + controlA.y + " " + controlB.x + "," + controlB.y + " "
388  + endPoint.x + "," + endPoint.y + "\n");
389  pathStringB += ("C " + controlA.x + "," + controlA.z + " " + controlB.x + "," + controlB.z + " "
390  + endPoint.x + "," + endPoint.z + "\n");
391  // start.set(0, sections.get(3).x);
392  // start.set(1, sections.get(3).y);
393  // start.set(2,sections.get(3).z);
394 
395  } else if (sections.size() == 1) {
396 
397  pathStringA += "L " + (double) sections.get(0).x + "," + (double) sections.get(0).y + "\n";
398  pathStringB += "L " + (double) sections.get(0).x + "," + (double) sections.get(0).z + "\n";
399  // start.set(0, sections.get(0).x);
400  // start.set(1, sections.get(0).y);
401  // start.set(2, sections.get(0).z);
402  }
403  }
404  // println "A string = " +pathStringA
405  // println "B String = " +pathStringB
406  BezierPath path = new BezierPath();
407  path.parsePathString(pathStringA);
408  BezierPath path2 = new BezierPath();
409  path2.parsePathString(pathStringB);
410 
411  return bezierToTransforms(path, path2, resolution, null, null);
412  }
413 
414  public static ArrayList<CSG> moveAlongProfile(CSG object, List<List<Vector3d>> points, int resolution) {
415 
416  return Extrude.move(object, pathToTransforms(points, resolution));
417  }
418 
419  public static ArrayList<Transform> bezierToTransforms(Vector3d controlA, Vector3d controlB, Vector3d endPoint,
420  int iterations) {
421  BezierPath path = new BezierPath();
422  path.parsePathString("C " + controlA.x + "," + controlA.y + " " + controlB.x + "," + controlB.y + " "
423  + endPoint.x + "," + endPoint.y);
424  BezierPath path2 = new BezierPath();
425  path2.parsePathString("C " + controlA.x + "," + controlA.z + " " + controlB.x + "," + controlB.z + " "
426  + endPoint.x + "," + endPoint.z);
427 
428  return bezierToTransforms(path, path2, iterations, controlA, controlB);
429  }
430 
431  public static ArrayList<Transform> bezierToTransforms(List<Vector3d> parts, int iterations) {
432  // System.out.println("Bezier type "+parts.size());
433  if (parts.size() == 3)
434  return bezierToTransforms(parts.get(0), parts.get(1), parts.get(2), iterations);
435  if (parts.size() == 2)
436  return bezierToTransforms(parts.get(0), parts.get(0), parts.get(1), parts.get(1), iterations);
437  if (parts.size() == 1)
438  return bezierToTransforms(new Vector3d(0, 0, 0), new Vector3d(0, 0, 0), parts.get(0), parts.get(0),
439  iterations);
440  return bezierToTransforms(parts.get(0), parts.get(1), parts.get(2), parts.get(3), iterations);
441  }
442 
443  private Transform toTransform() {
444 
445  return null;
446  }
447 
448  public static ArrayList<Transform> bezierToTransforms(BezierPath pathA, BezierPath pathB, int iterations,
449  Vector3d controlA, Vector3d controlB) {
450  double d = 1.0 / (double) iterations;
451  ArrayList<Transform> p = new ArrayList<Transform>();
452  Vector3d pointAStart = pathA.eval(0);
453  Vector3d pointBStart = pathB.eval(0);
454  double x = pointAStart.x, y = pointAStart.y, z = pointBStart.y;
455  double lastx = x, lasty = y, lastz = z;
456  // float min = (float) 0.0001;
457  int startIndex = 0;
458  if (controlA != null) {
459  startIndex = 1;
460  double ydiff = controlA.y - y;
461  double zdiff = controlA.z - z;
462  double xdiff = controlA.x - x;
463  double rise = zdiff;
464  double run = Math.sqrt((ydiff * ydiff) + (xdiff * xdiff));
465  double rotz = 90 - Math.toDegrees(Math.atan2(xdiff, ydiff));
466  // System.out.println("Rot z = "+rotz+" x="+xdiff+" y="+ydiff);
467  double roty = Math.toDegrees(Math.atan2(rise, run));
468  Transform t = new Transform();
469  t.translateX(x);
470  t.translateY(y);
471  t.translateZ(z);
472  t.rotZ(-rotz);
473  t.rotY(roty);
474  p.add(t);
475  }
476  Transform t;
477  double ydiff;
478  double zdiff;
479  double xdiff;
480  double rise;
481  double run;
482  double rotz;
483  double roty;
484  for (int i = startIndex; i < iterations - 1; i++) {
485  float pathFunction = (float) (((float) i) / ((float) (iterations - 1)));
486 
487  Vector3d pointA = pathA.eval(pathFunction);
488  Vector3d pointB = pathB.eval(pathFunction);
489 
490  x = pointA.x;
491  y = pointA.y;
492  z = pointB.y;
493 
494  t = new Transform();
495  t.translateX(x);
496  t.translateY(y);
497  t.translateZ(z);
498 
499  Vector3d pointAEst = pathA.eval((float) (pathFunction + d));
500  Vector3d pointBEst = pathB.eval((float) (pathFunction + d));
501  double xest = pointAEst.x;
502  double yest = pointAEst.y;
503  double zest = pointBEst.y;
504  ydiff = yest - y;
505  zdiff = zest - z;
506  xdiff = xest - x;
507  // t.rotX(45-Math.toDegrees(Math.atan2(zdiff,ydiff)))
508 
509  rise = zdiff;
510  run = Math.sqrt((ydiff * ydiff) + (xdiff * xdiff));
511  rotz = 90 - Math.toDegrees(Math.atan2(xdiff, ydiff));
512  // System.out.println("Rot z = "+rotz+" x="+xdiff+" y="+ydiff);
513  roty = Math.toDegrees(Math.atan2(rise, run));
514 
515  t.rotZ(-rotz);
516  t.rotY(roty);
517  // if(i==0)
518  // System.out.println( " Tr = "+x+" "+y+" "+z+" path = "+pathFunction);
519  // println "z = "+rotz+" y = "+roty
520  p.add(t);
521  lastx = x;
522  lasty = y;
523  lastz = z;
524  }
525 
526  Vector3d pointA = pathA.eval((float) 1);
527  Vector3d pointB = pathB.eval((float) 1);
528 
529  x = pointA.x;
530  y = pointA.y;
531  z = pointB.y;
532  t = new Transform();
533  t.translateX(x);
534  t.translateY(y);
535  t.translateZ(z);
536  if (controlB != null) {
537  lastx = controlB.x;
538  lasty = controlB.y;
539  lastz = controlB.z;
540  }
541 
542  ydiff = y - lasty;
543  zdiff = z - lastz;
544  xdiff = x - lastx;
545 
546  rise = zdiff;
547  run = Math.sqrt((ydiff * ydiff) + (xdiff * xdiff));
548  rotz = 90 - Math.toDegrees(Math.atan2(xdiff, ydiff));
549  roty = Math.toDegrees(Math.atan2(rise, run));
550 
551  t.rotZ(-rotz);
552  t.rotY(roty);
553  p.add(t);
554 
555  return p;
556  }
557 
558  public static ArrayList<Transform> bezierToTransforms(Vector3d start, Vector3d controlA, Vector3d controlB,
559  Vector3d endPoint, int iterations) {
560  String startString = "M " + start.x + "," + start.y + "\n" + "C " + controlA.x + "," + controlA.y + " "
561  + controlB.x + "," + controlB.y + " " + endPoint.x + "," + endPoint.y;
562  String b = "M " + start.x + "," + start.z + "\n" + "C " + controlA.x + "," + controlA.z + " " + controlB.x + ","
563  + controlB.z + " " + endPoint.x + "," + endPoint.z;
564  // println "Start = "+startString
565  BezierPath path = new BezierPath();
566  path.parsePathString(startString);
567  BezierPath path2 = new BezierPath();
568  path2.parsePathString(b);
569  // newParts.remove(parts.size()-1)
570  // newParts.remove(0)
571  // System.out.println("Parsing "+startString+" \nand\n"+b);
572  return bezierToTransforms(path, path2, iterations, controlA, controlB);
573  }
574 
575  public static ArrayList<CSG> revolve(CSG slice, double radius, int numSlices) {
576  return revolve(slice, radius, 360.0, null, numSlices);
577  }
578 
579  public static ArrayList<CSG> revolve(Polygon poly, int numSlices) {
580  return revolve(poly, 0, numSlices);
581  }
582 
583  public static ArrayList<CSG> revolve(Polygon poly, double radius, int numSlices) {
584  ArrayList<CSG> parts = new ArrayList<CSG>();
585  ArrayList<Polygon> slices = new ArrayList<Polygon>();
586 
587  for (int i = 0; i < numSlices; i++) {
588  double angle = 360.0 / ((double) numSlices) * ((double) i);
589  slices.add(poly.transformed(new Transform().movex(radius).roty(angle)));
590  }
591  for (int i = 0; i < slices.size(); i++) {
592  int next = i + 1;
593  if (next == slices.size())
594  next = 0;
595  // println "Extruding "+i+" to "+next
596  parts.add(Extrude.polygons(slices.get(i), slices.get(next)));
597  }
598 
599  return parts;
600  }
601 
602  public static ArrayList<CSG> revolve(CSG slice, double radius, double archLen, int numSlices) {
603  return revolve(slice, radius, archLen, null, numSlices);
604  }
605 
606  public static ArrayList<CSG> revolve(CSG slice, double radius, double archLen, List<List<Vector3d>> points,
607  int numSlices) {
608  ArrayList<CSG> parts = new ArrayList<CSG>();
609  double slices = (double) numSlices;
610  double increment = archLen / slices;
611  CSG slicePRofile = slice.movey(radius);
612 
613  for (double i = 0; i < (archLen + increment); i += increment) {
614  parts.add(slicePRofile.rotz(i));
615  }
616  if (points != null) {
617  ArrayList<Transform> pathtransforms = pathToTransforms(points, numSlices);
618  for (int i = 0; i < parts.size(); i++) {
619  CSG sweep = parts.get(i).transformed(pathtransforms.get(i));
620  parts.set(i, sweep);
621  }
622  }
623  for (int i = 0; i < parts.size() - 1; i++) {
624 
625  CSG sweep = CSG.hullAll(parts.get(i), parts.get(i + 1));
626  parts.set(i, sweep);
627  }
628 
629  return parts;
630  }
631 
632  public static ArrayList<CSG> bezier(CSG slice, ArrayList<Double> controlA, ArrayList<Double> controlB,
633  ArrayList<Double> endPoint, int numSlices) {
634  ArrayList<CSG> parts = new ArrayList<CSG>();
635 
636  for (int i = 0; i < numSlices; i++) {
637  parts.add(0, slice.clone());
638  }
639  return bezier(parts, controlA, controlB, endPoint);
640  }
641 
642  public static ArrayList<CSG> bezier(ArrayList<CSG> s, ArrayList<Double> controlA, ArrayList<Double> controlB,
643  ArrayList<Double> endPoint) {
644  ArrayList<CSG> slice = moveBezier(s, controlA, controlB, endPoint);
645 
646  for (int i = 0; i < slice.size() - 1; i++) {
647  // Polygon p1 =Slice.slice(slice.get(i), new Transform(), 0).get(0);
648  // Polygon p2 =Slice.slice(slice.get(i+1), new Transform(), 0).get(0);
649  // CSG sweep = polygons(p1, p2);
650  CSG sweep = HullUtil.hull(slice.get(i), slice.get(i + 1));
651 
652  slice.set(i, sweep);
653  }
654  return slice;
655  }
656 
657  public static ArrayList<CSG> hull(ArrayList<CSG> s, ArrayList<Transform> p) {
658  ArrayList<CSG> slice = move(s, p);
659  for (int i = 0; i < slice.size() - 1; i++) {
660  // Polygon p1 =Slice.slice(slice.get(i), new Transform(), 0).get(0);
661  // Polygon p2 =Slice.slice(slice.get(i+1), new Transform(), 0).get(0);
662  // CSG sweep = polygons(p1, p2);
663  CSG sweep = HullUtil.hull(slice.get(i), slice.get(i + 1));
664 
665  slice.set(i, sweep);
666  }
667  return slice;
668  }
669 
670  public static ArrayList<CSG> hull(CSG c, ArrayList<Transform> p) {
671  ArrayList<CSG> s = new ArrayList<>();
672  for (int i = 0; i < p.size(); i++) {
673  s.add(c.clone());
674  }
675  return hull(s, p);
676  }
677 
678  public static ArrayList<CSG> linear(ArrayList<CSG> s, ArrayList<Double> endPoint) {
679  ArrayList<Double> start = (ArrayList<Double>) Arrays.asList(0.0, 0.0, 0.0);
680  return bezier(s, start, endPoint, endPoint);
681  }
682 
683  public static ArrayList<CSG> linear(CSG s, ArrayList<Double> endPoint, int numSlices) {
684  ArrayList<Double> start = (ArrayList<Double>) Arrays.asList(0.0, 0.0, 0.0);
685 
686  return bezier(s, start, endPoint, endPoint, numSlices);
687  }
688 
689  public static ArrayList<CSG> move(ArrayList<CSG> slice, ArrayList<Transform> p) {
690 
691  return CSG.move(slice, p);
692  }
693 
694  public static ArrayList<CSG> move(CSG slice, ArrayList<Transform> p) {
695  return slice.move(p);
696  }
697 
698  public static ArrayList<CSG> moveBezier(CSG slice, ArrayList<Double> controlA, ArrayList<Double> controlB,
699  ArrayList<Double> endPoint, int numSlices) {
700  ArrayList<Transform> p = bezierToTransforms(fromDouble(controlA), fromDouble(controlB), fromDouble(endPoint),
701  numSlices);
702 
703  return move(slice, p);
704  }
705 
706  public static ArrayList<CSG> moveBezier(ArrayList<CSG> slice, ArrayList<Double> controlA,
707  ArrayList<Double> controlB, ArrayList<Double> endPoint) {
708 
709  int numSlices = slice.size();
710  ArrayList<Transform> p = bezierToTransforms(fromDouble(controlA), fromDouble(controlB), fromDouble(endPoint),
711  numSlices);
712  return move(slice, p);
713 
714  }
715 
716  private static Vector3d fromDouble(ArrayList<Double> controlA) {
717  return new Vector3d(controlA.get(0), controlA.get(1), controlA.get(2));
718  }
719 
720  public static ArrayList<CSG> moveBezier(CSG slice, BezierPath pathA, int numSlices) {
721  Vector3d pointA = pathA.eval((float) 1.0);
722  String zpath = "C 0,0 " + pointA.x + "," + pointA.y + " " + pointA.x + "," + pointA.y;
723  BezierPath pathB = new BezierPath();
724  pathB.parsePathString(zpath);
725 
726  return moveBezier(slice, pathA, pathB, numSlices);
727 
728  }
729 
730  public static ArrayList<CSG> moveBezier(CSG slice, BezierPath pathA, BezierPath pathB, int iterations) {
731 
732  ArrayList<Transform> p = bezierToTransforms(pathA, pathB, iterations, null, null);
733  return move(slice, p);
734 
735  }
736 
737  public static Polygon toCCW(Polygon concave) {
738  if (!isCCW(concave)) {
739  List<Vector3d> points = concave.getPoints();
740  List<Vector3d> result = new ArrayList<>(points);
741  Collections.reverse(result);
742  return Polygon.fromPoints(result);
743  }
744  return concave;
745  }
746 }
void parsePathString(String d)
Definition: BezierPath.java:29
Vector3d eval(float interp)
CSG transformed(Transform transform)
Definition: CSG.java:1676
CSG rotz(Number degreesToRotate)
Definition: CSG.java:550
CSG move(Number x, Number y, Number z)
Definition: CSG.java:406
static CSG hullAll(CSG... csgs)
Definition: CSG.java:880
CSG movey(Number howFarToMove)
Definition: CSG.java:429
static CSG fromPolygons(List< Polygon > polygons)
Definition: CSG.java:621
static boolean isCCW(Polygon polygon)
Definition: Extrude.java:258
static ArrayList< CSG > moveBezier(CSG slice, BezierPath pathA, int numSlices)
Definition: Extrude.java:720
static ArrayList< CSG > revolve(Polygon poly, int numSlices)
Definition: Extrude.java:579
static ArrayList< Transform > pathToTransforms(List< List< Vector3d >> points, int resolution)
Definition: Extrude.java:364
static ArrayList< CSG > bezier(CSG slice, ArrayList< Double > controlA, ArrayList< Double > controlB, ArrayList< Double > endPoint, int numSlices)
Definition: Extrude.java:632
static ArrayList< CSG > revolve(CSG slice, double radius, double archLen, int numSlices)
Definition: Extrude.java:602
static List< Vector3d > toCCW(List< Vector3d > points)
Definition: Extrude.java:224
static ArrayList< CSG > polygons(eu.mihosoft.vrl.v3d.Polygon polygon1, Transform... transformparts)
Definition: Extrude.java:193
static ArrayList< CSG > moveBezier(CSG slice, ArrayList< Double > controlA, ArrayList< Double > controlB, ArrayList< Double > endPoint, int numSlices)
Definition: Extrude.java:698
static double normalizedX(Vector3d v1, Vector3d v2)
Definition: Extrude.java:326
static ArrayList< CSG > revolve(Polygon poly, double radius, int numSlices)
Definition: Extrude.java:583
static CSG points(Vector3d dir, Vector3d... points)
Definition: Extrude.java:213
static CSG points(Vector3d dir, List< Vector3d > points)
Definition: Extrude.java:199
static void setExtrusionEngine(IExtrusion extrusionEngine)
Definition: Extrude.java:336
static Polygon toCCW(Polygon concave)
Definition: Extrude.java:737
static ArrayList< CSG > moveAlongProfile(CSG object, List< List< Vector3d >> points, int resolution)
Definition: Extrude.java:414
static CSG byPath(List< List< Vector3d >> points, double height, int resolution)
Definition: Extrude.java:346
static Vector3d fromDouble(ArrayList< Double > controlA)
Definition: Extrude.java:716
static ArrayList< CSG > bezier(ArrayList< CSG > s, ArrayList< Double > controlA, ArrayList< Double > controlB, ArrayList< Double > endPoint)
Definition: Extrude.java:642
static ArrayList< CSG > moveBezier(ArrayList< CSG > slice, ArrayList< Double > controlA, ArrayList< Double > controlB, ArrayList< Double > endPoint)
Definition: Extrude.java:706
static ArrayList< Transform > bezierToTransforms(Vector3d start, Vector3d controlA, Vector3d controlB, Vector3d endPoint, int iterations)
Definition: Extrude.java:558
static ArrayList< CSG > linear(CSG s, ArrayList< Double > endPoint, int numSlices)
Definition: Extrude.java:683
static ArrayList< CSG > hull(CSG c, ArrayList< Transform > p)
Definition: Extrude.java:670
static ArrayList< Transform > bezierToTransforms(Vector3d controlA, Vector3d controlB, Vector3d endPoint, int iterations)
Definition: Extrude.java:419
static ArrayList< CSG > move(ArrayList< CSG > slice, ArrayList< Transform > p)
Definition: Extrude.java:689
static ArrayList< CSG > revolve(CSG slice, double radius, double archLen, List< List< Vector3d >> points, int numSlices)
Definition: Extrude.java:606
static ArrayList< Transform > bezierToTransforms(BezierPath pathA, BezierPath pathB, int iterations, Vector3d controlA, Vector3d controlB)
Definition: Extrude.java:448
static ArrayList< CSG > linear(ArrayList< CSG > s, ArrayList< Double > endPoint)
Definition: Extrude.java:678
static ArrayList< Transform > bezierToTransforms(List< Vector3d > parts, int iterations)
Definition: Extrude.java:431
static IExtrusion extrusionEngine
Definition: Extrude.java:56
static ArrayList< CSG > revolve(CSG slice, double radius, int numSlices)
Definition: Extrude.java:575
static ArrayList< CSG > move(CSG slice, ArrayList< Transform > p)
Definition: Extrude.java:694
static CSG polygons(Polygon polygon1, Polygon polygon2)
Definition: Extrude.java:134
static CSG polygons(Polygon polygon1, Number zDistance)
Definition: Extrude.java:130
static ArrayList< CSG > polygons(eu.mihosoft.vrl.v3d.Polygon polygon1, ArrayList< Transform > transforms)
Definition: Extrude.java:174
static IExtrusion getExtrusionEngine()
Definition: Extrude.java:332
static ArrayList< CSG > hull(ArrayList< CSG > s, ArrayList< Transform > p)
Definition: Extrude.java:657
static ArrayList< CSG > moveBezier(CSG slice, BezierPath pathA, BezierPath pathB, int iterations)
Definition: Extrude.java:730
static CSG byPath(List< List< Vector3d >> points, double height)
Definition: Extrude.java:340
final List< Vertex > vertices
Definition: Polygon.java:54
List< Vector3d > getPoints()
Definition: Polygon.java:547
static Polygon fromPoints(List< Vector3d > points, PropertyStorage shared)
Definition: Polygon.java:386
Polygon translated(Vector3d v)
Definition: Polygon.java:327
PropertyStorage getStorage()
Definition: Polygon.java:534
Polygon transformed(Transform transform)
Definition: Polygon.java:375
Transform roty(Number degreesToRotate)
Definition: Transform.java:705
Transform rotZ(double degrees)
Definition: Transform.java:140
Transform translateZ(double value)
Definition: Transform.java:313
Transform rotY(double degrees)
Definition: Transform.java:123
Transform translateX(double value)
Definition: Transform.java:217
Transform translateY(double value)
Definition: Transform.java:299
Transform movex(Number howFarToMove)
Definition: Transform.java:653
Vector3d times(double a)
Definition: Vector3d.java:191
static final Vector3d X_ONE
Definition: Vector3d.java:63
static Vector3d y(double y)
Definition: Vector3d.java:484
Vector3d minus(Vector3d v)
Definition: Vector3d.java:178
static Vector3d z(double z)
Definition: Vector3d.java:494
static Vector3d x(double x)
Definition: Vector3d.java:474
Vector3d dividedBy(double a)
Definition: Vector3d.java:217
static List< eu.mihosoft.vrl.v3d.Polygon > concaveToConvex(eu.mihosoft.vrl.v3d.Polygon incoming)
CSG extrude(Vector3d dir, List< Vector3d > points)