Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy the color of the polygon on triangulation #58

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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());
});
}
}
Loading