Skip to content

Commit 4d37aac

Browse files
committed
Regeress the split plane algo
1 parent 622d5e8 commit 4d37aac

File tree

4 files changed

+112
-99
lines changed

4 files changed

+112
-99
lines changed

src/main/java/eu/mihosoft/vrl/v3d/Plane.java

+79-80
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ private enum PlaneType {
204204
*/
205205
public void splitPolygon(Polygon polygon, List<Polygon> coplanarFront, List<Polygon> coplanarBack,
206206
List<Polygon> front, List<Polygon> back) {
207-
// final int COPLANAR = 0;
208-
// final int FRONT = 1;
209-
// final int BACK = 2;
210-
// final int SPANNING = 3; // == some in the FRONT + some in the BACK
207+
final int COPLANAR = 0;
208+
final int FRONT = 1;
209+
final int BACK = 2;
210+
final int SPANNING = 3; // == some in the FRONT + some in the BACK
211211
if (debugger != null && useDebugger) {
212212
// debugger.display(polygon);
213213
// debugger.display(coplanarFront);
@@ -219,26 +219,25 @@ public void splitPolygon(Polygon polygon, List<Polygon> coplanarFront, List<Poly
219219
double negEpsilon = polygon.getNegEpsilon();
220220
double posEpsilon = polygon.getPosEpsilon();
221221

222-
PlaneType polygonType = PlaneType.COPLANAR;
223-
List<PlaneType> types = new ArrayList<>();
222+
int polygonType = 0;
223+
List<Integer> types = new ArrayList<>();
224224
boolean somePointsInfront = false;
225225
boolean somePointsInBack = false;
226226
for (int i = 0; i < polygon.size(); i++) {
227227
double t = this.getNormal().dot(polygon.get(i).pos) - this.getDist();
228-
PlaneType type = (t < negEpsilon) ? PlaneType.BACK
229-
: (t > posEpsilon) ? PlaneType.FRONT : PlaneType.COPLANAR;
230-
if (type == PlaneType.BACK)
228+
int type = (t < negEpsilon) ? BACK : (t > posEpsilon) ? FRONT : COPLANAR;
229+
if (type == BACK)
231230
somePointsInBack = true;
232-
if (type == PlaneType.FRONT)
231+
if (type == FRONT)
233232
somePointsInfront = true;
234233
types.add(type);
235234
}
236235
if (somePointsInBack && somePointsInfront)
237-
polygonType = PlaneType.SPANNING;
236+
polygonType = SPANNING;
238237
else if (somePointsInBack) {
239-
polygonType = PlaneType.BACK;
238+
polygonType = BACK;
240239
} else if (somePointsInfront)
241-
polygonType = PlaneType.FRONT;
240+
polygonType = FRONT;
242241

243242
// Put the polygon in the correct list, splitting it when necessary.
244243
switch (polygonType) {
@@ -252,88 +251,88 @@ else if (somePointsInBack) {
252251
back.add(polygon);
253252
break;
254253
case SPANNING:
255-
ArrayList<Vertex> f = new ArrayList<>();
256-
ArrayList<Vertex> b = new ArrayList<>();
254+
List<Vertex> f = new ArrayList<>();
255+
List<Vertex> b = new ArrayList<>();
257256
for (int i = 0; i < polygon.size(); i++) {
258257
int j = (i + 1) % polygon.size();
259-
PlaneType ti = types.get(i);
260-
PlaneType tj = types.get(j);
258+
int ti = types.get(i);
259+
int tj = types.get(j);
261260
Vertex vi = polygon.get(i);
262261
Vertex vj = polygon.get(j);
263-
if (ti != PlaneType.BACK) {
264-
f.add(vi.clone());
262+
if (ti != BACK) {
263+
f.add(vi);
265264
}
266-
if (ti != PlaneType.FRONT) {
267-
b.add(vi.clone());
265+
if (ti != FRONT) {
266+
b.add(ti != BACK ? vi.clone() : vi);
268267
}
269-
if ((ti == PlaneType.FRONT && tj == PlaneType.BACK)
270-
|| (ti == PlaneType.BACK && tj == PlaneType.FRONT)) {
268+
if ((ti | tj) == SPANNING) {
271269
double t = (this.getDist() - this.getNormal().dot(vi.pos))
272270
/ this.getNormal().dot(vj.pos.minus(vi.pos));
273-
if (t > 1)
274-
t = 1;
275-
if (t < 0)
276-
t = 0;
277271
Vertex v = vi.interpolate(vj, t);
278272
f.add(v);
279273
b.add(v.clone());
280274
}
281275
}
282-
283-
try {
284-
Polygon frontPoly = new Polygon(f, polygon.getStorage(), polygon.plane).setColor(polygon.getColor());
285-
if (f.size() == 3)
286-
front.add(frontPoly);
287-
else
288-
try {
289-
front.addAll(PolygonUtil.triangulate(frontPoly));
290-
} catch (Exception e) {
291-
throw e;
292-
}
293-
} catch (InvalidNormalException e) {
294-
// Auto-generated catch block
295-
e.printStackTrace();
296-
} catch (TooFewPointsException e) {
297-
// Auto-generated catch block
298-
e.printStackTrace();
299-
} catch (PointsColinearException e) {
300-
// Auto-generated catch block
301-
e.printStackTrace();
302-
} catch (PointsNotCoplainer e) {
303-
// Auto-generated catch block
304-
e.printStackTrace();
305-
} catch (java.lang.IllegalStateException e) {
306-
// Auto-generated catch block
307-
e.printStackTrace();
276+
if (f.size() >= 3) {
277+
try {
278+
Polygon frontPoly = new Polygon(f, polygon.getStorage(), polygon.plane).setColor(polygon.getColor());
279+
if (f.size() == 3)
280+
front.add(frontPoly);
281+
else
282+
try {
283+
front.addAll(PolygonUtil.triangulate(frontPoly));
284+
} catch (Exception e) {
285+
throw e;
286+
}
287+
} catch (InvalidNormalException e) {
288+
// Auto-generated catch block
289+
e.printStackTrace();
290+
} catch (TooFewPointsException e) {
291+
// Auto-generated catch block
292+
e.printStackTrace();
293+
} catch (PointsColinearException e) {
294+
// Auto-generated catch block
295+
e.printStackTrace();
296+
} catch (PointsNotCoplainer e) {
297+
// Auto-generated catch block
298+
e.printStackTrace();
299+
} catch (java.lang.IllegalStateException e) {
300+
// Auto-generated catch block
301+
e.printStackTrace();
302+
}
303+
} else {
304+
// com.neuronrobotics.sdk.common.Log.error("Front Clip Fault!");
308305
}
309-
310-
try {
311-
Polygon backPoly = new Polygon(b, polygon.getStorage(), polygon.plane).setColor(polygon.getColor());
312-
if (b.size() == 3)
313-
back.add(backPoly);
314-
else
315-
try {
316-
back.addAll(PolygonUtil.triangulate(backPoly));
317-
} catch (Exception e) {
318-
throw e;
319-
}
320-
} catch (InvalidNormalException e) {
321-
// Auto-generated catch block
322-
e.printStackTrace();
323-
} catch (TooFewPointsException e) {
324-
// Auto-generated catch block
325-
e.printStackTrace();
326-
} catch (PointsColinearException e) {
327-
// Auto-generated catch block
328-
e.printStackTrace();
329-
} catch (PointsNotCoplainer e) {
330-
// Auto-generated catch block
331-
e.printStackTrace();
332-
} catch (java.lang.IllegalStateException e) {
333-
// Auto-generated catch block
334-
e.printStackTrace();
306+
if (b.size() >= 3) {
307+
try {
308+
Polygon backPoly = new Polygon(b, polygon.getStorage(), polygon.plane).setColor(polygon.getColor());
309+
if (b.size() == 3)
310+
back.add(backPoly);
311+
else
312+
try {
313+
back.addAll(PolygonUtil.triangulate(backPoly));
314+
} catch (Exception e) {
315+
throw e;
316+
}
317+
} catch (InvalidNormalException e) {
318+
// Auto-generated catch block
319+
e.printStackTrace();
320+
} catch (TooFewPointsException e) {
321+
// Auto-generated catch block
322+
e.printStackTrace();
323+
} catch (PointsColinearException e) {
324+
// Auto-generated catch block
325+
e.printStackTrace();
326+
} catch (PointsNotCoplainer e) {
327+
// Auto-generated catch block
328+
e.printStackTrace();
329+
} catch (java.lang.IllegalStateException e) {
330+
// Auto-generated catch block
331+
e.printStackTrace();
332+
}
333+
} else {
334+
// com.neuronrobotics.sdk.common.Log.error("Back Clip Fault!");
335335
}
336-
337336
break;
338337
}
339338
}

src/main/java/eu/mihosoft/vrl/v3d/Polygon.java

+24-12
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ public final class Polygon {
6464
*/
6565
public Plane plane=null;
6666
private boolean isHole = false;
67-
private boolean allowDegenerate;
6867

6968
/**
7069
* Constructor. Creates a new polygon that consists of the specified vertices.
@@ -81,7 +80,6 @@ public final class Polygon {
8180
*/
8281
public Polygon(List<Vertex> vertices, PropertyStorage shared, Plane p)
8382
throws InvalidNormalException, TooFewPointsException, PointsColinearException, PointsNotCoplainer {
84-
this.allowDegenerate = allowDegenerate;
8583
if(p!=null)
8684
plane=p.clone();
8785
this.vertices = pruneDuplicatePoints(vertices);
@@ -230,7 +228,6 @@ public ArrayList<Vertex> pruneDuplicatePoints(List<Vertex> incoming) {
230228
}
231229
}
232230
if (!duplicate) {
233-
// v.pos.roundToEpsilon();
234231
newPoints.add(v);
235232
}
236233

@@ -239,7 +236,7 @@ public ArrayList<Vertex> pruneDuplicatePoints(List<Vertex> incoming) {
239236
return newPoints;
240237

241238
}
242-
239+
private boolean throwErrorExceptions = false;
243240
public void validateAndInit()
244241
throws InvalidNormalException, TooFewPointsException, PointsColinearException, PointsNotCoplainer {
245242
if (plane == null)
@@ -248,27 +245,42 @@ public void validateAndInit()
248245
this.shared = new PropertyStorage();
249246
for (Vertex v : vertices) {
250247
v.normal = plane.getNormal();
251-
// v.pos.roundToEpsilon();
248+
//v.pos.roundToEpsilon(Plane.getEPSILON());
252249
}
253250
//setDegenerate(true);
254251
if (Vector3d.ZERO.equals(plane.getNormal())) {
255252
valid = false;
256-
throw new InvalidNormalException(
253+
InvalidNormalException e= new InvalidNormalException(
257254
"Normal is zero! Probably, duplicate points have been specified!\n\n" + toStlString());
255+
e.printStackTrace();
256+
if(throwErrorExceptions)
257+
throw e;
258258
}
259259

260260
if (vertices.size() < 3) {
261-
throw new TooFewPointsException("Invalid polygon: at least 3 vertices expected, got: " + vertices.size());
261+
TooFewPointsException e= new TooFewPointsException("Invalid polygon: at least 3 vertices expected, got: " + vertices.size());
262+
e.printStackTrace();
263+
if(throwErrorExceptions)
264+
throw e;
262265
}
263266

264-
if (areAllPointsCollinear(vertices))
265-
throw new PointsColinearException("This polygon is colinear");
267+
if (areAllPointsCollinear(vertices)) {
268+
PointsColinearException e= new PointsColinearException("This polygon is colinear");
269+
e.printStackTrace();
270+
if(throwErrorExceptions)
271+
throw e;
272+
}
266273

267274
if(!arePointsCoplanar()) {
268-
throw new PointsNotCoplainer("All points are not on plane of epsilon "+Plane.getEPSILON());
275+
PointsNotCoplainer e= new PointsNotCoplainer("All points are not on plane of epsilon "+Plane.getEPSILON());
276+
e.printStackTrace();
277+
if(throwErrorExceptions)
278+
throw e;
269279
}
270-
setNegEpsilon(-Plane.getEPSILON());
271-
setPosEpsilon(Plane.getEPSILON());
280+
281+
282+
// setNegEpsilon(-Plane.getEPSILON());
283+
// setPosEpsilon(Plane.getEPSILON());
272284
}
273285

274286

src/main/java/eu/mihosoft/vrl/v3d/Vector3d.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ public StringBuilder toObjString(StringBuilder sb) {
363363
*/
364364
private double roundToEpsilon(double value,double epsilon) {
365365
// Round to nearest multiple of epsilon
366-
return value;// ((double)Math.round(value / epsilon)) * epsilon;
366+
return ((double)Math.round(value / epsilon)) * epsilon;
367367
}
368368
private String roundedValue(double v,double ep) {
369369
return String.format(getExportString(), roundToEpsilon(v,ep));

src/test/java/eu/mihosoft/vrl/v3d/StlExportTest.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,28 @@ public class StlExportTest {
1212

1313
@Test
1414
public void makeBadSTL() throws IOException, InvalidNormalException, TooFewPointsException, PointsColinearException, PointsNotCoplainer {
15-
Plane.setEPSILON(1.0e-9);
15+
Plane.setEPSILON(1.0e-12);
1616
//Vector3d.setEXPORTEPSILON(1.0e-12);
1717
CSG.setUseGPU(false);
1818
CSG.setPreventNonManifoldTriangles(false);
1919
CSG badExport2 = CSG.text(" A QUICK BROWN ", 10,30,"Serif Regular").movey(30);
2020
System.out.println("First text loaded");
2121
CSG badExport = CSG.text("THis is some text a", 10);
22-
System.out.println("Second text loaded");
22+
2323
// badExport2=new Cube(20).toCSG().movey(30);
2424
// badExport=new Cube(20).toCSG();
2525

2626
badExport=badExport.union(badExport2);
2727
//String filename ="TextStl.stl";
28+
System.out.println("Writing first STL");
2829
FileUtil.write(Paths.get("TextStl.stl"),
2930
badExport.toStlString());
3031
// System.out.println("Load saved stl");
31-
// File file = new File("TextStl.stl");
32-
// //CSG.setPreventNonManifoldTriangles(false);
33-
//
34-
// CSG loaded = STL.file(file.toPath());
32+
File file = new File("TextStl.stl");
33+
//CSG.setPreventNonManifoldTriangles(false);
34+
35+
CSG loaded = STL.file(file.toPath());
36+
System.out.println("STL text loaded");
3537
// System.out.println("Perform difference");
3638
// badExport=loaded.scaleToMeasurmentX(160).scaleToMeasurmentY(30);
3739
// badExport=new Cube(180,40,10).toCSG().toZMin().toXMin().toYMin().movey(-5).difference(badExport).rotx(35).roty(45);

0 commit comments

Comments
 (0)