我将JCSG与以下代码结合使用,使用两个多边形(一个大和一个小)制作一个带孔的三角形。我希望它看起来像附件中的图像,但是结果是一个空的STL。
java - JCSG差异生成空的STL。这是我的错误还是错误?-LMLPHP

    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中使用。

java - JCSG差异生成空的STL。这是我的错误还是错误?-LMLPHP

这是源代码:

差异表面:

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);
 }

}

09-30 17:40