我将JCSG与以下代码结合使用,使用两个多边形(一个大和一个小)制作一个带孔的三角形。我希望它看起来像附件中的图像,但是结果是一个空的STL。
List<Vector3d> t1 = new ArrayList<>();
t1.add(Vector3d.xyz(0, 0, 0));
t1.add(Vector3d.xyz(100, 0, 0));
t1.add(Vector3d.xyz(0, 100, 0));
List<Polygon> poly1 = Polygon.fromConcavePoints(t1);
CSG csg1 = CSG.fromPolygons(poly1);
List<Vector3d> t2 = new ArrayList<>();
t2.add(Vector3d.xyz(10, 10, 0));
t2.add(Vector3d.xyz(80, 10, 0));
t2.add(Vector3d.xyz(10, 80, 0));
List<Polygon> poly2 = Polygon.fromConcavePoints(t2);
CSG csg2 = CSG.fromPolygons(poly2);
CSG csg = csg1.difference(csg2);
String stl = csg.toStlString();
System.out.println(stl);
结果是:
固体v3d.csg
最终版本v3d.csg
最佳答案
JCSG仅适用于封闭的表面,即不适用于没有体积的表面。但是无论如何,您都可以使用一个技巧:
1. extrude your polygons by 1
2. perform the difference operation
3. select all polygons that are in the XY-plane and save them as STL
下面是一个VRL-Studio示例(屏幕截图和代码),演示了如何在JCSG中完成差值运算和XY平面选择。代码是Groovy,但它与Java接近。所有功能也可以在没有VRL-Studio的普通JCSG中使用。
这是源代码:
差异表面:
import eu.mihosoft.jcsg.Extrude;
import java.util.List;
import eu.mihosoft.jcsg.CSG;
import eu.mihosoft.jcsg.Polygon;
import eu.mihosoft.vvecmath.Transform;
import eu.mihosoft.vvecmath.Vector3d as Vec3d;
import eu.mihosoft.vvecmath.Vectors3d as Vecs;
@ComponentInfo(name="DiffSurface", category="Custom")
@groovy.transform.CompileStatic
public class DiffSurface implements java.io.Serializable {
private static final long serialVersionUID=1L;
// *** DOES NOT WORK (SURFACE IS NOT CLOSED) ***
public CSG diff1() {
List<Vec3d> t1 = new ArrayList<>();
t1.add(Vec3d.xyz(0, 0, 0));
t1.add(Vec3d.xyz(100, 0, 0));
t1.add(Vec3d.xyz(0, 100, 0));
List<Polygon> poly1 = Polygon.fromConcavePoints(t1);
CSG csg1 = CSG.fromPolygons(poly1);
List<Vec3d> t2 = new ArrayList<>();
t2.add(Vec3d.xyz(10, 10, 0));
t2.add(Vec3d.xyz(80, 10, 0));
t2.add(Vec3d.xyz(10, 80, 0));
List<Polygon> poly2 = Polygon.fromConcavePoints(t2);
CSG csg2 = CSG.fromPolygons(poly2);
CSG csg = csg1.difference(csg2);
return csg
}
// *** WORKS (SURFACE CLOSED) ***
public CSG diff2(double height) {
List<Vec3d> t1 = new ArrayList<>();
t1.add(Vec3d.xyz(0, 0, 0));
t1.add(Vec3d.xyz(100, 0, 0));
t1.add(Vec3d.xyz(0, 100, 0));
// EXTRUDE Triangle 1
CSG csg1 = Extrude.points(Vec3d.z(height), t1)
List<Vec3d> t2 = new ArrayList<>();
t2.add(Vec3d.xyz(10, 10, 0));
t2.add(Vec3d.xyz(80, 10, 0));
t2.add(Vec3d.xyz(10, 80, 0));
// EXTRUDE Triangle 2
CSG csg2 = Extrude.points(Vec3d.z(height), t2)
CSG csg = csg1.difference(csg2);
return csg
}
}
ReduceToXYPlane:
import eu.mihosoft.jcsg.Extrude;
import java.util.List;
import eu.mihosoft.jcsg.CSG;
import eu.mihosoft.jcsg.Polygon;
import eu.mihosoft.vvecmath.Transform;
import eu.mihosoft.vvecmath.Vector3d as Vec3d;
import eu.mihosoft.vvecmath.Vectors3d as Vecs;
@ComponentInfo(name="Reduce", category="Custom")
public class Reduce implements java.io.Serializable {
private static final long serialVersionUID=1L;
// add your code here
public CSG reduce(CSG csg) {
List<Polygon> result = new ArrayList<>();
// for each polygon in the CSG object
for (Polygon poly : csg.getPolygons()) {
// store all vertices in the X,Y plane
// in a vertex list
List<Vec3d> vertices = new ArrayList<>();
poly.vertices.each{v ->
if (Math.abs(v.pos.z) < 1e-6) {
vertices.add(v.pos)
}
}
// if more than 2 vertices are in the list
// create a polygon and add it to the
// polygon list
if(vertices.size()>2) {
Polygon p = Polygon.fromPoints(vertices);
result.add(p)
}
}
// create a CSG from polygons that can be exported
// as STL
//
// NOTE: performing CSG operations on this CSG
// will result in invalid computations.
// Only use non-closed CSG for converting to STL files
return CSG.fromPolygons(result);
}
}