Example #1
0
  private void optimizePoints() {
    int total = 0, duplicates = 0, check = 0;

    Map<Point3D, Integer> pp = new HashMap<>();
    ObservableIntegerArray reindex = FXCollections.observableIntegerArray();
    ObservableFloatArray newPoints = FXCollections.observableFloatArray();

    for (MeshView meshView : meshViews) {
      TriangleMesh mesh = (TriangleMesh) meshView.getMesh();
      ObservableFloatArray points = mesh.getPoints();
      int pointElementSize = mesh.getPointElementSize();
      int os = points.size() / pointElementSize;

      pp.clear();
      newPoints.clear();
      newPoints.ensureCapacity(points.size());
      reindex.clear();
      reindex.resize(os);

      for (int i = 0, oi = 0, ni = 0; i < points.size(); i += pointElementSize, oi++) {
        float x = points.get(i);
        float y = points.get(i + 1);
        float z = points.get(i + 2);
        Point3D p = new Point3D(x, y, z);
        Integer index = pp.get(p);
        if (index == null) {
          pp.put(p, ni);
          reindex.set(oi, ni);
          newPoints.addAll(x, y, z);
          ni++;
        } else {
          reindex.set(oi, index);
        }
      }

      int ns = newPoints.size() / pointElementSize;

      int d = os - ns;
      duplicates += d;
      total += os;

      points.setAll(newPoints);
      points.trimToSize();

      ObservableIntegerArray faces = mesh.getFaces();
      for (int i = 0; i < faces.size(); i += 2) {
        faces.set(i, reindex.get(faces.get(i)));
      }

      //            System.out.printf("There are %d (%.2f%%) duplicate points out of %d total for
      // mesh '%s'.\n",
      //                    d, 100d * d / os, os, meshView.getId());

      check += mesh.getPoints().size() / pointElementSize;
    }
    System.out.printf(
        "There are %d (%.2f%%) duplicate points out of %d total.\n",
        duplicates, 100d * duplicates / total, total);
    System.out.printf("Now we have %d points.\n", check);
  }
Example #2
0
  private void optimizeFaces() {
    int total = 0, sameIndexes = 0, samePoints = 0, smallArea = 0;
    ObservableIntegerArray newFaces = FXCollections.observableIntegerArray();
    ObservableIntegerArray newFaceSmoothingGroups = FXCollections.observableIntegerArray();
    for (MeshView meshView : meshViews) {
      TriangleMesh mesh = (TriangleMesh) meshView.getMesh();
      ObservableIntegerArray faces = mesh.getFaces();
      ObservableIntegerArray faceSmoothingGroups = mesh.getFaceSmoothingGroups();
      ObservableFloatArray points = mesh.getPoints();
      newFaces.clear();
      newFaces.ensureCapacity(faces.size());
      newFaceSmoothingGroups.clear();
      newFaceSmoothingGroups.ensureCapacity(faceSmoothingGroups.size());
      int pointElementSize = mesh.getPointElementSize();
      int faceElementSize = mesh.getFaceElementSize();
      for (int i = 0; i < faces.size(); i += faceElementSize) {
        total++;
        int i1 = faces.get(i) * pointElementSize;
        int i2 = faces.get(i + 2) * pointElementSize;
        int i3 = faces.get(i + 4) * pointElementSize;
        if (i1 == i2 || i1 == i3 || i2 == i3) {
          sameIndexes++;
          continue;
        }
        Point3D p1 = new Point3D(points.get(i1), points.get(i1 + 1), points.get(i1 + 2));
        Point3D p2 = new Point3D(points.get(i2), points.get(i2 + 1), points.get(i2 + 2));
        Point3D p3 = new Point3D(points.get(i3), points.get(i3 + 1), points.get(i3 + 2));
        if (p1.equals(p2) || p1.equals(p3) || p2.equals(p3)) {
          samePoints++;
          continue;
        }
        double a = p1.distance(p2);
        double b = p2.distance(p3);
        double c = p3.distance(p1);
        double p = (a + b + c) / 2;
        double sqarea = p * (p - a) * (p - b) * (p - c);

        final float DEAD_FACE = 1.f / 1024 / 1024 / 1024 / 1024; // taken from MeshNormal code

        if (sqarea < DEAD_FACE) {
          smallArea++;
          //                    System.out.printf("a = %e, b = %e, c = %e, sqarea = %e\n"
          //                            + "p1 = %s\np2 = %s\np3 = %s\n", a, b, c, sqarea,
          // p1.toString(), p2.toString(), p3.toString());
          continue;
        }
        newFaces.addAll(faces, i, faceElementSize);
        int fIndex = i / faceElementSize;
        if (fIndex < faceSmoothingGroups.size()) {
          newFaceSmoothingGroups.addAll(faceSmoothingGroups.get(fIndex));
        }
      }
      faces.setAll(newFaces);
      faceSmoothingGroups.setAll(newFaceSmoothingGroups);
      faces.trimToSize();
      faceSmoothingGroups.trimToSize();
    }
    int badTotal = sameIndexes + samePoints + smallArea;
    System.out.printf(
        "Removed %d (%.2f%%) faces with same point indexes, "
            + "%d (%.2f%%) faces with same points, "
            + "%d (%.2f%%) faces with small area. "
            + "Total %d (%.2f%%) bad faces out of %d total.\n",
        sameIndexes,
        100d * sameIndexes / total,
        samePoints,
        100d * samePoints / total,
        smallArea,
        100d * smallArea / total,
        badTotal,
        100d * badTotal / total,
        total);
  }