Skip to content

Commit

Permalink
Copy the color of the polygon on triangulation
Browse files Browse the repository at this point in the history
  • Loading branch information
breiler committed Aug 12, 2024
1 parent e35c8c6 commit 8868181
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 51 deletions.
4 changes: 2 additions & 2 deletions src/main/java/eu/mihosoft/vrl/v3d/CSG.java
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,7 @@ private CSG updatePolygons(ArrayList<Polygon> toAdd, ArrayList<Polygon> degenera
// System.out.println("Fixing error in STL " + name + " polygon# " + i + "
// number of vertices " + p.vertices.size());
try {
List<Polygon> triangles = PolygonUtil.concaveToConvex(p,true);
List<Polygon> triangles = PolygonUtil.concaveToConvex(p);
for(Polygon poly :triangles) {
if(poly.isDegenerate()) {
degenerates.add(poly);
Expand All @@ -1569,7 +1569,7 @@ private CSG updatePolygons(ArrayList<Polygon> toAdd, ArrayList<Polygon> degenera
Debug3dProvider.clearScreen();
Debug3dProvider.addObject(p);
try {
List<Polygon> triangles = PolygonUtil.concaveToConvex(p,true);
List<Polygon> triangles = PolygonUtil.concaveToConvex(p);
toAdd.addAll(triangles);
}catch(java.lang.IllegalStateException ise) {
ise.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.triangulate.polygon.ConstrainedDelaunayTriangulator;

// TODO: Auto-generated Javadoc
/**
* The Class PolygonUtil.
*
Expand Down Expand Up @@ -101,28 +100,23 @@ private PolygonUtil() {
* @param incoming the concave
* @return the list
*/
public static List<eu.mihosoft.vrl.v3d.Polygon> concaveToConvex(eu.mihosoft.vrl.v3d.Polygon incoming) {
return concaveToConvex(incoming,false);
}
public static List<eu.mihosoft.vrl.v3d.Polygon> concaveToConvex(eu.mihosoft.vrl.v3d.Polygon incoming, boolean strictTriangulation) {
//incoming = pruneDuplicatePoints(incoming);
public static List<Polygon> concaveToConvex(Polygon incoming) {
List<Polygon> result = new ArrayList<>();

if (incoming == null)
return result;
if (incoming.vertices.size() < 3)
return result;
eu.mihosoft.vrl.v3d.Polygon concave= incoming;;
Polygon concave = incoming;
Vector3d normalOfPlane = incoming.plane.normal;
boolean reorent = normalOfPlane.z < 1.0-Plane.EPSILON;
Transform orentationInv = null;
boolean debug = false;
Vector3d normal2;
if (reorent) {
double degreesToRotate = Math.toDegrees(Math.atan2(normalOfPlane.x,normalOfPlane.z));
Transform orentation = new Transform().roty(degreesToRotate);

eu.mihosoft.vrl.v3d.Polygon tmp = incoming.transformed(orentation);
Polygon tmp = incoming.transformed(orentation);

Vector3d normal = tmp.plane.normal;
double degreesToRotate2 =90+Math.toDegrees(Math.atan2(normal.z,normal.y));
Expand All @@ -133,22 +127,13 @@ public static List<eu.mihosoft.vrl.v3d.Polygon> concaveToConvex(eu.mihosoft.vrl.
Debug3dProvider.addObject(incoming);
}
concave = incoming.transformed(orentation2);
normal2 = concave.plane.normal;
orentationInv = orentation2.inverse();
if(concave.plane.normal.z <0) {
Transform orentation3 = orentation2.rotx(180);
concave = incoming.transformed(orentation3);
orentationInv = orentation3.inverse();
}


//System.out.println("New vectors "+normal2+" "+normal);
}
// if(concave.plane.normal.z < 0.999) {
// result.add(incoming);
// return result;
// //throw new RuntimeException("Orentaion of plane misaligned for triangulation "+concave.plane.normal.z);
// }


Vector3d normal = concave.plane.normal.clone();
Expand All @@ -170,22 +155,15 @@ public static List<eu.mihosoft.vrl.v3d.Polygon> concaveToConvex(eu.mihosoft.vrl.
Vector3d v = concave.vertices.get(0).pos;
coordinates[concave.vertices.size()]=new Coordinate(v.x,v.y,zplane);
// use the default factory, which gives full double-precision
//System.out.println("Triangulating\n"+geom.toText());
Geometry triangles;
try {
Geometry geom = new GeometryFactory().createPolygon(coordinates);
triangles= ConstrainedDelaunayTriangulator.triangulate(geom);
//System.out.println("Triangulation result\n"+triangles.toText());
}catch(Exception ex) {
ex.printStackTrace();
throw ex;
}
// eu.mihosoft.vrl.v3d.ext.org.poly2tri.LegacyPolygon p = fromCSGPolygon(concave);
// //System.out.println("Triangulating "+p);
// eu.mihosoft.vrl.v3d.ext.org.poly2tri.Poly2Tri.triangulate(p);
//
// List<DelaunayTriangle> triangles = p.getTriangles();


ArrayList<Vertex> triPoints = new ArrayList<>();

for (int i=0;i<triangles.getNumGeometries();i++) {
Expand All @@ -203,14 +181,14 @@ public static List<eu.mihosoft.vrl.v3d.Polygon> concaveToConvex(eu.mihosoft.vrl.
if (!cw) {
Collections.reverse(triPoints);
}
eu.mihosoft.vrl.v3d.Polygon poly = new eu.mihosoft.vrl.v3d.Polygon(triPoints, concave.getStorage(),true);
Polygon poly = new Polygon(triPoints, concave.getStorage(), true);
//poly = Extrude.toCCW(poly);
poly.plane.normal = concave.plane.normal;
boolean b = !Extrude.isCCW(poly);
if (cw != b) {
// System.out.println("Triangle not matching incoming");
Collections.reverse(triPoints);
poly = new eu.mihosoft.vrl.v3d.Polygon(triPoints, concave.getStorage(),true);
poly = new Polygon(triPoints, concave.getStorage(), true);
b = !Extrude.isCCW(poly);
if (cw != b) {
System.out.println("Error, polygon is reversed!");
Expand All @@ -226,16 +204,10 @@ public static List<eu.mihosoft.vrl.v3d.Polygon> concaveToConvex(eu.mihosoft.vrl.
poly = poly.transform(orentationInv);
}
poly.plane.normal = normalOfPlane;
//poly.setDegenerate(t.isDegenerate());
// System.out.println("Updating the normal to " + clone);
// if (debug) {
// Debug3dProvider.addObject(incoming);
// Debug3dProvider.addObject(poly);
// }
poly.setColor(incoming.getColor());
result.add(poly);
counter = 0;
triPoints = new ArrayList<>();

} else {
counter++;
}
Expand Down
70 changes: 56 additions & 14 deletions src/test/java/eu/mihosoft/vrl/v3d/CSGTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,15 @@

public class CSGTest {

public static final String BLUE_COLOR_AS_STRING = Color.BLUE.getRed() + " " + Color.BLUE.getGreen() + " " + Color.BLUE.getBlue();
public static final String RED_COLOR_AS_STRING = Color.RED.getRed() + " " + Color.RED.getGreen() + " " + Color.RED.getBlue();

private static String getColorAsString(Polygon polygon) {
Color c=polygon.getColor();
return c.getRed() + " " + c.getGreen() + " " + c.getBlue();
}

@Test
public void setColor_ShouldSetColorToAllPolygons() {
CSG cube = new Cube()
.toCSG()
.setColor(Color.BLUE);
assertEquals(Color.BLUE, cube.getColor());

String colorAsString = Color.BLUE.getRed() + " " + Color.BLUE.getGreen() + " " + Color.BLUE.getBlue();
cube.getPolygons().forEach(polygon -> {
String polygonColorAsString = getColorAsString(polygon);
assertEquals("Expected the polygon to get the same color as the CSG", colorAsString, polygonColorAsString);
assertEquals("Expected the polygon to get the same color as the CSG", Color.BLUE, polygon.getColor());
});
}

Expand All @@ -41,13 +31,65 @@ public void setColor_OnUnionCSGShouldRetainColorsOnPolygons() {
assertEquals(CSG.getDefaultColor(), union.getColor());

union.getPolygons().forEach(polygon -> {
String polygonColorAsString = getColorAsString(polygon);
boolean isLeftCube = polygon.getPoints().stream().allMatch(p -> p.x <= 5);
if (isLeftCube) {
assertEquals("Expected the left cube polygons to be blue", BLUE_COLOR_AS_STRING, polygonColorAsString);
assertEquals("Expected the left cube polygons to be blue", Color.BLUE, polygon.getColor());
} else {
assertEquals("Expected the right cube polygons to be red", Color.RED, polygon.getColor());
}
});
}

@Test
public void setColor_OnUnionedAndTriangulatedCSGShouldRetainColorsOnPolygons() {
CSG cube1 = new Cube(10).toCSG()
.setColor(Color.BLUE);

CSG cube2 = new Cube(10).toCSG()
.setColor(Color.RED)
.transformed(new Transform().translate(10, 0, 0));

CSG union = cube1.union(cube2).triangulate();
assertEquals(CSG.getDefaultColor(), union.getColor());

union.getPolygons().forEach(polygon -> {
boolean isLeftCube = polygon.getPoints().stream().allMatch(p -> p.x <= 5);
if (isLeftCube) {
assertEquals("Expected the left cube polygons to be blue", Color.BLUE, polygon.getColor());
} else {
assertEquals("Expected the right cube polygons to be red", RED_COLOR_AS_STRING, polygonColorAsString);
assertEquals("Expected the right cube polygons to be red", Color.RED, polygon.getColor());
}
});
}

@Test
public void setColor_OnCSGShouldChangeColorsOfAllPolygons() {
CSG cube = new Cube(10).toCSG()
.setColor(Color.BLUE);
assertEquals(Color.BLUE, cube.getColor());

cube.setColor(Color.RED);

cube.getPolygons().forEach(polygon -> {
assertEquals("Expected the cube polygons to be another color", Color.RED, polygon.getColor());
});
}

@Test
public void setColor_OnUnionedCSGShouldChangeColorsOfAllPolygons() {
CSG cube1 = new Cube(10).toCSG()
.setColor(Color.BLUE);

CSG cube2 = new Cube(10).toCSG()
.setColor(Color.RED)
.transformed(new Transform().translate(10, 0, 0));

CSG union = cube1.union(cube2);
assertEquals("Expected the new object to inherit the color from the latest unioned object", CSG.getDefaultColor(), union.getColor());

union.setColor(Color.BLUE);
union.getPolygons().forEach(polygon -> {
assertEquals("Expected the cube polygons to be another color", Color.BLUE, polygon.getColor());
});
}
}

0 comments on commit 8868181

Please sign in to comment.