/** @see boogiepants.model.Displayable#display() */
  public Node display() {
    Appearance a = new Appearance();
    Group shape = new Sphere(.15f, a);
    a.setColoringAttributes(new ColoringAttributes(.5f, .5f, 1f, ColoringAttributes.NICEST));
    a.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.NICEST, .3f));
    Transform3D t = new Transform3D();
    if (loPoint == null) {
      loPoint = new Point3d(0d, 0d, 0d);
    }
    t.set(new Vector3d(loPoint.x, loPoint.y, loPoint.z));
    transformGroupLo = new TransformGroup();
    transformGroupLo.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    transformGroupLo.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    transformGroupLo.setTransform(t);
    transformGroupLo.addChild(shape);
    loEndpoint = endpoint(loPoint, transformGroupLo);
    Shape3D geom = (Shape3D) shape.getChild(0);
    geom.setUserData(loEndpoint);

    a = new Appearance();
    shape = new Sphere(.15f, a);
    a.setColoringAttributes(new ColoringAttributes(1f, .5f, .5f, ColoringAttributes.NICEST));
    a.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.NICEST, .3f));
    t = new Transform3D();
    if (hiPoint == null) {
      hiPoint = new Point3d(0d, 0d, 0d);
    }
    t.set(new Vector3d(hiPoint.x, hiPoint.y, hiPoint.z));
    transformGroupHi = new TransformGroup();
    transformGroupHi.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    transformGroupHi.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    transformGroupHi.setTransform(t);
    transformGroupHi.addChild(shape);
    hiEndpoint = endpoint(hiPoint, transformGroupHi);
    geom = (Shape3D) shape.getChild(0);
    geom.setUserData(hiEndpoint);

    container = new BranchGroup();
    container.setCapability(BranchGroup.ALLOW_DETACH);
    container.addChild(transformGroupHi);
    container.addChild(transformGroupLo);
    stickGroup = BoogiepantsDisplayWindow.getInstance().getStickGroup();

    behavior = new ScaleInstrumentBehavior(oscaddress, loPoint, hiPoint, stickGroup);
    container.addChild(behavior);
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
    behavior.setSchedulingBounds(bounds);

    editGroup = new BranchGroup();
    editGroup.setCapability(BranchGroup.ALLOW_DETACH);
    editGroup.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
    editGroup.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
    container.addChild(editGroup);

    behavior.computeLineLen();

    return container;
  }
Example #2
0
  private BranchGroup setApperancePackInBranchGroup(Shape3D shape, Node handle) {
    shape.setUserData(this);

    shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);

    BranchGroup bg = new BranchGroup();
    bg.setCapability(BranchGroup.ALLOW_DETACH);
    bg.addChild(handle);
    bg.compile();
    return bg;
  }
 protected Shape3D createPointShape(Java3DParticlesGeometry pointShape) {
   int pointSize = 3;
   Appearance app = new Appearance();
   app.setCapability(app.ALLOW_POINT_ATTRIBUTES_READ);
   app.setCapability(app.ALLOW_POINT_ATTRIBUTES_WRITE);
   PointAttributes pattrib = new PointAttributes();
   pattrib.setPointSize(pointSize);
   app.setPointAttributes(pattrib);
   Shape3D pShape = new Shape3D(pointShape, app);
   pShape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
   pShape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
   return pShape;
 }
Example #4
0
  public BranchGroup addTriangle(Simplex simplex, Color3f color) {

    int[] p = simplex.getPoints();
    BranchGroup bgTriangle = new BranchGroup();
    bgTriangle.setCapability(BranchGroup.ALLOW_DETACH);

    javax.vecmath.Point3d[] coords = new javax.vecmath.Point3d[6];
    TriangleArray ta = new TriangleArray(6, TriangleArray.COORDINATES | TriangleArray.COLOR_3);

    Point3d p0 = (Point3d) complex.getPoints().get(simplex.getPoints()[0]);
    Point3d p1 = (Point3d) complex.getPoints().get(simplex.getPoints()[1]);
    Point3d p2 = (Point3d) complex.getPoints().get(simplex.getPoints()[2]);
    coords[0] = new javax.vecmath.Point3d(p0.getX(), p0.getY(), p0.getZ());
    coords[1] = new javax.vecmath.Point3d(p1.getX(), p1.getY(), p1.getZ());
    coords[2] = new javax.vecmath.Point3d(p2.getX(), p2.getY(), p2.getZ());
    coords[3] = new javax.vecmath.Point3d(p0.getX(), p0.getY(), p0.getZ());
    coords[4] = new javax.vecmath.Point3d(p2.getX(), p2.getY(), p2.getZ());
    coords[5] = new javax.vecmath.Point3d(p1.getX(), p1.getY(), p1.getZ());

    ta.setCoordinates(0, coords);
    Color3f[] colors = new Color3f[6];
    for (int i = 0; i < 3; i++) colors[i] = Colors.black;
    for (int i = 3; i < 6; i++) colors[i] = Colors.yellow;

    ta.setColors(0, colors);

    Appearance ap = new Appearance();
    ap.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_READ);
    ap.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_WRITE);
    ap.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_READ);
    ap.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE);
    ap.setLineAttributes(new LineAttributes(2, LineAttributes.PATTERN_SOLID, false));
    ap.setMaterial(new Material());
    ap.setTransparencyAttributes(
        new TransparencyAttributes(TransparencyAttributes.SCREEN_DOOR, 0.5f));

    Shape3D shape = new Shape3D(ta, ap);

    shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
    shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
    simplex.setTriangle(shape);
    //			 simplex.bgTriangle = bgTriangle;

    TransformGroup tgTriangle = new TransformGroup();
    tgTriangle.addChild(shape);

    bgTriangle.addChild(tgTriangle);
    spin.addChild(bgTriangle);
    return bgTriangle;
  }
Example #5
0
 public void setApperance() {
   Appearance app = null;
   if (state == FILL.POINT) app = new PointAppearance(color);
   else if (state == FILL.GRID) app = new GridAppearance(color);
   else app = new ColorAppearance(color);
   shape.setAppearance(app);
 }
Example #6
0
  /**
   * Sets the appearance.
   *
   * @param shape the new appearance
   */
  private void setAppearance(Shape3D shape) {
    Appearance sphereApp = new Appearance();
    TransparencyAttributes sphereTrans = new TransparencyAttributes();
    PolygonAttributes spherePa = new PolygonAttributes();

    spherePa.setCullFace(PolygonAttributes.CULL_NONE);
    sphereApp.setPolygonAttributes(spherePa);
    sphereTrans.setTransparency(0.6f);
    sphereTrans.setTransparencyMode(TransparencyAttributes.NICEST);
    sphereApp.setTransparencyAttributes(sphereTrans);
    shape.setAppearance(sphereApp);
  }
Example #7
0
 public static void initShape(Shape3D shape) {
   shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
   shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
   shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_READ);
   shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE);
   shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
   shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
 }
  @Deprecated
  public void addText(String text, Font3D font, Color3f color, Point3f position) {
    Text3D renderedText = new Text3D(font, text);
    renderedText.setAlignment(Text3D.ALIGN_CENTER);

    Shape3D textShape = new Shape3D();
    textShape.setGeometry(renderedText);
    textShape.setAppearance(
        Utils.makeAppearance(getSettings().getPolygonSettings().toJ3DPolygonAttributes(), color));
    textShape.setBounds(getSettings().getRenderSettings3D().getBounds());

    Transform3D transform = new Transform3D();
    transform.setTranslation(new Vector3f(position));
    // Math3D.scale(transformations, DEFAULT_SCALE);

    TransformGroup transformations = new TransformGroup();

    transformations.setTransform(transform);
    transformations.addChild(textShape);

    getScene().addChild(transformations);
    getLogger().info("Text ('" + text + "') added to scene.");
  }
Example #9
0
  /**
   * Simple algorithm to add or remove an edge from the selection Ideas: 1. Use one shape per quad
   * => easy, but can become very fast too big to fit in memory. => pb: flicker when adding /
   * removing because the scene is detached 2. Use only one shape, modify geometry TODO: pre-create
   * an empty shape to avoid initial flicker
   *
   * @param on
   * @param p
   * @param u
   * @param v
   * @param groupIdx2
   */
  protected void toggleSelectedEdge(boolean on, SelectionEdge se) {
    if (on) {
      // add the given edge to the list
      if (edgeSelection.contains(se)) return; // already in
      edgeSelection.add(se);
    } else {
      // remove the given edge from the list
      if (!edgeSelection.contains(se)) return; // not present
      edgeSelection.remove(se);
      if (edgeSelection.size() == 0) {
        LineArray la = (LineArray) edgeSelectionShape.getGeometry();
        la.setValidVertexCount(0);
        return;
      }
    }
    // Use in-memory arrays instead of NIO because edgeSelection should not
    // be too big
    // => faster
    LineArray la =
        new LineArray(
            edgeSelection.size() * 2,
            GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.BY_REFERENCE);
    double[] coords = new double[edgeSelection.size() * 2 * 3];
    float[] colors = new float[edgeSelection.size() * 2 * 3];

    for (int i = 0; i < coords.length; i += 6) {
      SelectionEdge edge = edgeSelection.get(i / 6);
      edge.updateCoords(grid, coords, i);
      edge.updateColors(colors, i);
    }
    la.setCoordRefDouble(coords);
    la.setColorRefFloat(colors);
    la.setCapability(GeometryArray.ALLOW_COUNT_WRITE);
    // update edgeSelection Shape with the new edgeSelection list
    if (edgeSelectionShape == null) {
      Appearance a = new Appearance();
      // PolygonAttributes pa = new
      // PolygonAttributes(PolygonAttributes.POLYGON_LINE,
      // PolygonAttributes.CULL_NONE, 0);
      // pa.setPolygonOffset(1); // above edges
      // pa.setPolygonOffsetFactor(1);
      LineAttributes lat = new LineAttributes();
      lat.setLineWidth(2.0f);
      lat.setLineAntialiasingEnable(true);
      a.setLineAttributes(lat);
      // a.setPolygonAttributes(pa);
      edgeSelectionShape = new Shape3D(la, a);
      edgeSelectionShape.setUserData(this);
      edgeSelectionShape.setPickable(false);
      edgeSelectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
      edgeSelectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);

      BranchGroup bg = new BranchGroup();
      bg.addChild(edgeSelectionShape);
      addChild(bg);
    } else edgeSelectionShape.setGeometry(la);
  }
Example #10
0
  private void createTriangle() {
    int[] stripCount = {3};

    GeometryInfo gi = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
    gi.setCoordinates(points);
    gi.setStripCounts(stripCount);

    NormalGenerator ng = new NormalGenerator();
    ng.generateNormals(gi);
    gi.recomputeIndices();

    Stripifier st = new Stripifier();
    st.stripify(gi);
    gi.recomputeIndices();

    Appearance appearance = new Appearance();
    Material material = new Material();
    material.setAmbientColor(new Color3f(Color.GREEN));
    appearance.setMaterial(material);

    shape3D = new Shape3D();
    shape3D.setGeometry(gi.getGeometryArray());
    shape3D.setAppearance(appearance);
  }
Example #11
0
  protected void makeWires() {
    Wire[] wires = createWireList();

    if (wires.length == 0) return;

    FloatBuffer nioWires =
        ByteBuffer.allocateDirect(wires.length * 2 * 3 * 4)
            .order(ByteOrder.nativeOrder())
            .asFloatBuffer();

    for (int i = 0; i < wires.length; i++) {
      nioWires.put(wires[i].getCoordinates(grid));
    }

    // Create edge shapes directly, don't make it appear in graph
    LineArray la =
        new NioLineArray(wires.length * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
    la.setCoordRefBuffer(new J3DBuffer(nioWires));
    int colSize = wires.length * 2 * 3;
    FloatBuffer nioWireColors =
        ByteBuffer.allocateDirect(colSize * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
    float[] colors = getColorForOrder(-2, 0);
    for (int i = 0; i < colSize; i += 3) nioWireColors.put(colors);
    la.setColorRefBuffer(new J3DBuffer(nioWireColors));
    la.setUserData(new int[] {-2, 0});
    Appearance a = new Appearance();
    // PolygonAttributes pa = new
    // PolygonAttributes(PolygonAttributes.POLYGON_LINE,
    // PolygonAttributes.CULL_NONE, 0);
    // pa.setPolygonOffset(2);
    // pa.setPolygonOffsetFactor(2);
    // a.setPolygonAttributes(pa);
    /*
     * LineAttributes lat = new LineAttributes(); lat.setLineWidth(2.0f);
     * a.setLineAttributes(lat);
     */
    Shape3D s3d = new Shape3D(la, a);
    PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL);
    s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
    s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
    s3d.setCapability(Node.ALLOW_PICKABLE_READ);
    s3d.setCapability(Node.ALLOW_PICKABLE_WRITE);
    s3d.setPickable(true); // by default, can be changed with actions
    s3d.setUserData(this); // this object will handle edges
    addChild(s3d);
    allEdgeShapes.add(s3d);
  }
Example #12
0
  /**
   * Simple algorithm to add or remove a quad from the selection Ideas: 1. Use one shape per quad =>
   * easy, but can become very fast too big to fit in memory. => pb: flicker when adding / removing
   * because the scene is detached 2. Use only one shape, modify geometry TODO: pre-create an empty
   * shape to avoid initial flicker
   *
   * @param on
   * @param p
   * @param u
   * @param v
   * @param groupIdx2
   */
  protected void toggleSelectedQuad(boolean on, SelectionQuad sq) {
    LOGGER.finest("on=" + on + " selectionQuad=" + sq);
    if (on) {
      // add the given quad to the list
      if (selection.contains(sq)) return; // already in
      selection.add(sq);
    } else {
      // remove the given quad from the list
      if (!selection.contains(sq)) return; // not present
      selection.remove(sq);
      if (selection.size() == 0) {
        QuadArray qa = (QuadArray) selectionShape.getGeometry();
        qa.setValidVertexCount(0);
        return;
      }
    }
    // Use in-memory arrays instead of NIO because selection should not be
    // too big
    // => faster
    QuadArray qa =
        new QuadArray(
            selection.size() * 4,
            GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.BY_REFERENCE);
    float[] coords = new float[selection.size() * 4 * 3];
    float[] colors = new float[selection.size() * 4 * 3];

    for (int i = 0; i < coords.length; i += 12) {
      SelectionQuad quad = selection.get(i / 12);
      quad.updateCoords(grid, coords, i);
      quad.updateColors(colors, i);
    }
    qa.setCoordRefFloat(coords);
    qa.setColorRefFloat(colors);
    qa.setCapability(GeometryArray.ALLOW_COUNT_WRITE);
    // update selection Shape with the new selection list
    if (selectionShape == null) {
      Appearance a = new Appearance();
      PolygonAttributes pa =
          new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0);
      pa.setPolygonOffset(0.5f); // between faces and edges
      pa.setPolygonOffsetFactor(0.5f);
      a.setPolygonAttributes(pa);
      selectionShape = new Shape3D(qa, a);
      selectionShape.setUserData(this);
      selectionShape.setPickable(false);
      selectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
      selectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
      BranchGroup bg = new BranchGroup();
      bg.addChild(selectionShape);
      addChild(bg);
    } else selectionShape.setGeometry(qa);
  }
  public static Mesh readMeshFromObj(String path) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(path));
    String mtlLibPath = "";
    String materialName = "";

    ArrayList<Vector3d> vertices = new ArrayList<Vector3d>();
    ArrayList<Point3f> points = new ArrayList<Point3f>();
    ArrayList<Triangle> triangles = new ArrayList<Triangle>();
    ArrayList<Integer> coordIndices = new ArrayList<Integer>();
    while (true) {
      String line = reader.readLine();
      if (line == null) {
        reader.close();
        break;
      }
      if (line.startsWith("mtllib ")) { // mtllib location
        mtlLibPath = path.substring(0, path.lastIndexOf(File.separator) + 1) + line.substring(7);
      } else if (line.startsWith("v ")) { // vertex
        double[] coords = parseDoubles(line.substring(2));
        Vector3d vertex = new Vector3d(coords);
        Point3f point = new Point3f(vertex);
        vertices.add(vertex);
        points.add(point);
      } else if (line.startsWith("usemtl ")) {
        materialName = line.substring(7);
      } else if (line.startsWith("f ")) { // face (triangle)
        line = line.substring(2);
        String[] coords = line.split(" ");
        Vector<Integer> triangle = new Vector<Integer>();
        for (String coord : coords) {
          String[] coordInfos = coord.split("/");
          Integer coordIndex = Integer.parseInt(coordInfos[0]) - 1;
          triangle.add(coordIndex);
          coordIndices.add(coordIndex);
        }
        triangles.add(new Triangle(triangle.get(0), triangle.get(1), triangle.get(2)));
      }
    }

    int[] coordinateIndices = new int[coordIndices.size()];
    for (int j = 0; j < coordinateIndices.length; j++) {
      coordinateIndices[j] = coordIndices.get(j);
    }
    IndexedTriangleArray geometry =
        new IndexedTriangleArray(
            vertices.size(), IndexedTriangleArray.COORDINATES, coordIndices.size());
    geometry.setCoordinates(0, points.toArray(new Point3f[0]));
    geometry.setCoordinateIndices(0, coordinateIndices);
    GeometryInfo geometryInfo = new GeometryInfo(geometry);
    NormalGenerator normalGenerator = new NormalGenerator((float) Math.toRadians(10));
    normalGenerator.generateNormals(geometryInfo);

    // Material
    reader = new BufferedReader(new FileReader(new File(mtlLibPath)));

    // Default
    Color3f ambientColour = new Color3f(0.2f, 0.2f, 0.2f);
    Color3f diffuseColour = new Color3f(0.8f, 0.8f, 0.8f);
    Color3f specularColour = new Color3f(0.5f, 0.5f, 0.5f);
    Color3f emissiveColour = new Color3f(0.0f, 0.0f, 0.0f);
    float shininess = 50.0f;

    String currentMaterial = "";
    while (true) {
      String line = reader.readLine();
      if (line == null) {
        reader.close();
        break;
      }
      if (line.startsWith("newmtl ")) {
        currentMaterial = line.substring(7);
      } else if (currentMaterial.equals(materialName)) {
        if (line.startsWith("Ka ")) {
          // ambient color
          ambientColour = new Color3f(parseFloats(line.substring(3)));
        } else if (line.startsWith("Kd ")) {
          // diffuse color
          diffuseColour = new Color3f(parseFloats(line.substring(3)));
        } else if (line.startsWith("Ks ")) {
          // specular color
          specularColour = new Color3f(parseFloats(line.substring(3)));
        } else if (line.startsWith("Ns ")) {
          // specular coefficient
          shininess = Float.parseFloat(line.substring(3));
        }
      }
    }

    Appearance app = new Appearance();
    app.setMaterial(
        new Material(ambientColour, emissiveColour, diffuseColour, specularColour, shininess));
    Shape3D shape = new Shape3D(geometryInfo.getGeometryArray(), app);
    shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);

    Mesh mesh =
        new Mesh(
            vertices.toArray(new Vector3d[0]),
            triangles.toArray(new Triangle[0]),
            ambientColour,
            diffuseColour,
            specularColour,
            emissiveColour,
            shininess,
            shape);
    return mesh;
  }
Example #14
0
 /*
  * (non-Javadoc)
  *
  * @see syn3d.base.ActiveNode#highlight(boolean, java.lang.Object)
  */
 public void highlight(boolean on, Object parameter) {
   System.out.println("Total memory: " + Runtime.getRuntime().totalMemory());
   System.out.println("Free memory: " + Runtime.getRuntime().freeMemory());
   System.out.println(System.currentTimeMillis() + " starting highlight with " + parameter);
   if (parameter instanceof PickResult) {
     PickResult result = (PickResult) parameter;
     result.setFirstIntersectOnly(true);
     PickIntersection pi = result.getIntersection(0);
     // indices of the picked quad
     // Indices are set to vertex indices, as this is not an Index
     // Geometry object
     // => easy to find the plate index from this
     int[] idx = pi.getPrimitiveCoordinateIndices();
     int plateNum = idx[0] / 4;
     Plate p = plates[plateNum];
     Point3d point3d = pi.getPointCoordinates();
     point3d.get(point);
     FloatBuffer coords =
         (FloatBuffer) ((NioQuadArray) (shape.getGeometry())).getCoordRefBuffer().getBuffer();
     for (int i = 0; i < idx.length; ++i) {
       coords.position(idx[i] * 3);
       coords.get(vertices[i]);
     }
     int d1 = 0, d2 = 0;
     if (p instanceof PlateX) {
       d1 = 1;
       d2 = 2;
     } else if (p instanceof PlateY) {
       d1 = 0;
       d2 = 2;
     } else if (p instanceof PlateZ) {
       d1 = 0;
       d2 = 1;
     }
     int u =
         (int)
             Math.floor(
                 (point[d1] - vertices[0][d1])
                     * (p.max1 - p.min1)
                     / (vertices[3][d1] - vertices[0][d1]));
     int v =
         (int)
             Math.floor(
                 (point[d2] - vertices[0][d2])
                     * (p.max2 - p.min2)
                     / (vertices[1][d2] - vertices[0][d2]));
     int quadIdx = v * (p.max1 - p.min1) + u;
     u += p.min1;
     v += p.min2;
     System.out.println(
         (on ? "" : "de") + "selected quad " + quadIdx + " in plate " + plateNum + " in group ");
     System.out.println("Grid positions for the quad (x,y,z) indices:");
     int[] pos = p.getXYZGridIndices(u, v);
     System.out.println("vertex1 = (" + pos[0] + ", " + pos[1] + ", " + pos[2] + ")");
     pos = p.getXYZGridIndices(u, v + 1);
     System.out.println("vertex2 = (" + pos[0] + ", " + pos[1] + ", " + pos[2] + ")");
     pos = p.getXYZGridIndices(u + 1, v + 1);
     System.out.println("vertex3 = (" + pos[0] + ", " + pos[1] + ", " + pos[2] + ")");
     pos = p.getXYZGridIndices(u + 1, v);
     System.out.println("vertex4 = (" + pos[0] + ", " + pos[1] + ", " + pos[2] + ")");
     float[] color = getColorForOrder(groupIdx, on ? 1 : 0);
     for (int i = 0; i < idx.length; ++i) {
       colors.position(idx[i] * 3);
       colors.put(color);
     }
     toggleSelectedQuad(on, new SelectionQuad(p, u, v, groupIdx));
     // Use event propagation, but don't call
     // setAppearanceForHighlight
     FloatBuffer tmp = colors;
     colors = null;
     colors = tmp;
   }
   System.out.println(System.currentTimeMillis() + " end of highlight");
 }
Example #15
0
 public BehindShape(Shape3D s3d, Plate[] plates, int g) {
   this.shape = s3d;
   this.groupIdx = g;
   colors = (FloatBuffer) ((NioQuadArray) (shape.getGeometry())).getColorRefBuffer().getBuffer();
   this.plates = plates;
 }
Example #16
0
  protected void makeGroups() {
    int totalQuads = 0;
    int totalInternalEdges = 0;
    int totalExternalEdges = 0;
    // loop over each group
    // loop over each group
    int[] groupID = provider.getDomainIDs();

    for (int g = 0; g < groupID.length; ++g) {
      LOGGER.finest("generating java3d tree for group number " + groupID[g]);
      // Set of EdgeLine objects. Overlapping edges on the same line are
      // merged together
      HashMap<EdgeLine, EdgeLine> externalEdges = new HashMap<EdgeLine, EdgeLine>();
      // Same trick for internal edges.
      HashMap<EdgeLine, EdgeLine> internalEdges = new HashMap<EdgeLine, EdgeLine>();
      FDDomain fdDomain = (FDDomain) provider.getDomain(groupID[g]);
      baseColor.put(new Integer(g), fdDomain.getColor());
      Plate[] plates = domainToPlates(fdDomain);

      if (plates.length == 0) continue;

      // Create plates for this group
      FloatBuffer nioCoords =
          ByteBuffer.allocateDirect(plates.length * 4 * 3 * 4)
              .order(ByteOrder.nativeOrder())
              .asFloatBuffer();
      FloatBuffer nioColors =
          ByteBuffer.allocateDirect(plates.length * 4 * 3 * 4)
              .order(ByteOrder.nativeOrder())
              .asFloatBuffer();
      float[] baseColor = getColorForOrder(g, 0);
      // System.out.println(baseColor[0]+" "+baseColor[1]+" "+baseColor[2]);
      for (int np = 0; np < plates.length; ++np) {
        Plate p = plates[np];
        // put coordinates
        nioCoords.put(p.getCoordinates(grid));
        // put colors for the 4 vertices
        nioColors.put(baseColor);
        nioColors.put(baseColor);
        nioColors.put(baseColor);
        nioColors.put(baseColor);
        // Merge external edges
        addEdge(externalEdges, getLine(p, 2, p.min1), p.min2, p.max2);
        addEdge(externalEdges, getLine(p, 2, p.max1), p.min2, p.max2);
        addEdge(externalEdges, getLine(p, 1, p.min2), p.min1, p.max1);
        addEdge(externalEdges, getLine(p, 1, p.max2), p.min1, p.max1);
        // Merge internal edges
        for (int i = p.min1 + 1; i < p.max1; ++i)
          addEdge(internalEdges, getLine(p, 2, i), p.min2, p.max2);
        for (int j = p.min2 + 1; j < p.max2; ++j)
          addEdge(internalEdges, getLine(p, 1, j), p.min1, p.max1);
      }
      // use by reference array of colors => fast to change!
      QuadArray qa =
          new NioQuadArray(plates.length * 4, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
      qa.setCoordRefBuffer(new J3DBuffer(nioCoords));
      qa.setColorRefBuffer(new J3DBuffer(nioColors));
      qa.setCapability(GeometryArray.ALLOW_COLOR_WRITE);
      qa.setCapabilityIsFrequent(GeometryArray.ALLOW_COLOR_WRITE);
      Appearance a = new Appearance();
      PolygonAttributes pa =
          new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0);
      pa.setPolygonOffset(1);
      pa.setPolygonOffsetFactor(1);
      a.setPolygonAttributes(pa);
      Shape3D s3d = new Shape3D(qa, a);
      PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL);
      s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
      s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
      s3d.setCapability(Node.ALLOW_PICKABLE_READ);
      s3d.setCapability(Node.ALLOW_PICKABLE_WRITE);
      s3d.setPickable(true);
      s3d.setUserData(new BehindShape(s3d, plates, g));

      this.addChild(s3d);

      // Create edge shapes directly, don't make them appear in graph
      int nInternalEdges = 0;
      for (Iterator<EdgeLine> it = internalEdges.keySet().iterator(); it.hasNext(); ) {
        EdgeLine el = it.next();
        nInternalEdges += el.getNumberOfEdges();
      }
      if (nInternalEdges > 0) {
        DoubleBuffer nioInternalEdges =
            ByteBuffer.allocateDirect(nInternalEdges * 2 * 3 * 8)
                .order(ByteOrder.nativeOrder())
                .asDoubleBuffer();
        // create edge coords
        for (Iterator<EdgeLine> it = internalEdges.keySet().iterator(); it.hasNext(); ) {
          EdgeLine el = it.next();
          nioInternalEdges.put(el.getCoords(grid));
        }
        LineArray la =
            new NioLineArray(nInternalEdges * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
        la.setCoordRefBuffer(new J3DBuffer(nioInternalEdges));
        int colSize = nInternalEdges * 2 * 3;
        FloatBuffer nioInternalColors =
            ByteBuffer.allocateDirect(colSize * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        float[] colors = getColorForOrder(g, 2);
        for (int i = 0; i < colSize; i += 3) nioInternalColors.put(colors);
        la.setColorRefBuffer(new J3DBuffer(nioInternalColors));
        la.setUserData(new int[] {g, 2});
        a = new Appearance();
        // pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE,
        // PolygonAttributes.CULL_NONE, 0);
        // pa.setPolygonOffset(4);
        // pa.setPolygonOffsetFactor(4);
        // a.setPolygonAttributes(pa);
        // LineAttributes lat = new LineAttributes();
        // lat.setLineAntialiasingEnable(true);
        // a.setLineAttributes(lat);
        // RenderingAttributes ra = new RenderingAttributes();
        // ra.setAlphaTestFunction(RenderingAttributes.GREATER);
        // ra.setAlphaTestValue(0.5f);
        // a.setRenderingAttributes(ra);
        s3d = new Shape3D(la, a);
        PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL);
        s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
        s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
        s3d.setCapability(Node.ALLOW_PICKABLE_READ);
        s3d.setCapability(Node.ALLOW_PICKABLE_WRITE);
        s3d.setPickable(false); // by default, see actions
        s3d.setUserData(this); // this object will handle edges
        this.addChild(s3d);
        allEdgeShapes.add(s3d);
      }
      // Now, create external edge
      int nExternalEdges = 0;
      for (Iterator<EdgeLine> it = externalEdges.keySet().iterator(); it.hasNext(); ) {
        EdgeLine el = it.next();
        nExternalEdges += el.getNumberOfEdges();
      }
      if (nExternalEdges > 0) {
        DoubleBuffer nioExternalEdges =
            ByteBuffer.allocateDirect(nExternalEdges * 2 * 3 * 8)
                .order(ByteOrder.nativeOrder())
                .asDoubleBuffer();
        // create edge coords
        for (Iterator<EdgeLine> it = externalEdges.keySet().iterator(); it.hasNext(); ) {
          EdgeLine el = it.next();
          nioExternalEdges.put(el.getCoords(grid));
        }
        LineArray la =
            new NioLineArray(nExternalEdges * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
        la.setCoordRefBuffer(new J3DBuffer(nioExternalEdges));
        int colSize = nExternalEdges * 2 * 3;
        FloatBuffer nioExternalColors =
            ByteBuffer.allocateDirect(colSize * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        float[] colors = getColorForOrder(g, 4);
        for (int i = 0; i < colSize; i += 3) nioExternalColors.put(colors);
        la.setColorRefBuffer(new J3DBuffer(nioExternalColors));
        la.setUserData(new int[] {g, 4});
        a = new Appearance();
        // pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE,
        // PolygonAttributes.CULL_NONE, 0);
        // pa.setPolygonOffset(3);
        // pa.setPolygonOffsetFactor(3);
        // a.setPolygonAttributes(pa);
        s3d = new Shape3D(la, a);
        PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL);
        s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
        s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
        s3d.setCapability(Node.ALLOW_PICKABLE_READ);
        s3d.setCapability(Node.ALLOW_PICKABLE_WRITE);
        s3d.setPickable(false); // by default, see actions
        s3d.setUserData(this); // this object will handle edges
        this.addChild(s3d);
        allEdgeShapes.add(s3d);
      }
      totalQuads += plates.length;
      totalInternalEdges += nInternalEdges;
      totalExternalEdges += nExternalEdges;
    }
    System.out.println("Total quads: " + totalQuads);
    System.out.println("Total Internal Plate edges: " + totalInternalEdges);
    System.out.println("Total External Plate edges: " + totalExternalEdges);
  }
Example #17
0
  public BranchGroup addTetrahedron(Simplex simplex, Color3f color) {

    BranchGroup bgTetrahedron = new BranchGroup();
    bgTetrahedron.setCapability(BranchGroup.ALLOW_DETACH);

    javax.vecmath.Point3d[] coords = new javax.vecmath.Point3d[12];
    LineArray la = new LineArray(12, LineArray.COORDINATES | LineArray.COLOR_3);

    Point3d p0 = (Point3d) complex.getPoints().get(simplex.getPoints()[0]);
    Point3d p1 = (Point3d) complex.getPoints().get(simplex.getPoints()[1]);
    Point3d p2 = (Point3d) complex.getPoints().get(simplex.getPoints()[2]);
    Point3d p3 = (Point3d) complex.getPoints().get(simplex.getPoints()[3]);

    coords[0] = coords[2] = coords[4] = new javax.vecmath.Point3d(p0.getX(), p0.getY(), p0.getZ());
    coords[1] = coords[6] = coords[8] = new javax.vecmath.Point3d(p1.getX(), p1.getY(), p1.getZ());
    coords[3] = coords[7] = coords[10] = new javax.vecmath.Point3d(p2.getX(), p2.getY(), p2.getZ());
    coords[5] = coords[9] = coords[11] = new javax.vecmath.Point3d(p3.getX(), p3.getY(), p3.getZ());

    la.setCoordinates(0, coords);
    Color3f[] colors = new Color3f[12];
    for (int i = 0; i < 12; i++) colors[i] = Colors.black;
    la.setColors(0, colors);

    javax.vecmath.Point3d[] coordsTr = new javax.vecmath.Point3d[24];
    TriangleArray tr = new TriangleArray(24, TriangleArray.COORDINATES | TriangleArray.COLOR_3);
    coordsTr[0] =
        coordsTr[3] = coordsTr[6] = new javax.vecmath.Point3d(p0.getX(), p0.getY(), p0.getZ());
    coordsTr[1] =
        coordsTr[4] = coordsTr[9] = new javax.vecmath.Point3d(p1.getX(), p1.getY(), p1.getZ());
    coordsTr[2] =
        coordsTr[7] = coordsTr[10] = new javax.vecmath.Point3d(p2.getX(), p2.getY(), p2.getZ());
    coordsTr[5] =
        coordsTr[8] = coordsTr[11] = new javax.vecmath.Point3d(p3.getX(), p3.getY(), p3.getZ());

    coordsTr[12] =
        coordsTr[15] = coordsTr[18] = new javax.vecmath.Point3d(p0.getX(), p0.getY(), p0.getZ());
    coordsTr[14] =
        coordsTr[17] = coordsTr[21] = new javax.vecmath.Point3d(p1.getX(), p1.getY(), p1.getZ());
    coordsTr[13] =
        coordsTr[20] = coordsTr[23] = new javax.vecmath.Point3d(p2.getX(), p2.getY(), p2.getZ());
    coordsTr[16] =
        coordsTr[19] = coordsTr[22] = new javax.vecmath.Point3d(p3.getX(), p3.getY(), p3.getZ());

    tr.setCoordinates(0, coordsTr);
    Color3f[] colorsTr = new Color3f[24];
    for (int i = 0; i < 24; i++) colorsTr[i] = Colors.green;
    tr.setColors(0, colorsTr);

    Appearance ap = new Appearance();
    ap.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_READ);
    ap.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_WRITE);
    ap.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_READ);
    ap.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE);
    //			 ap.setCapability(Appearance.ALLOW_MATERIAL_READ);
    //			 ap.setCapability(Appearance.ALLOW_MATERIAL_WRITE);
    ap.setLineAttributes(new LineAttributes(2, LineAttributes.PATTERN_SOLID, false));
    ap.setMaterial(new Material());
    //			 ap.setTransparencyAttributes(new
    // TransparencyAttributes(TransparencyAttributes.SCREEN_DOOR, 0.5f));

    //			 LineArray la = cell.getLineArray();
    Shape3D shape = new Shape3D(la, ap);
    Shape3D shapeTr = new Shape3D(tr, ap);

    shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
    shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
    simplex.setTetrahedron(shape);
    //			 cell.setLineArray(la);
    simplex.setTriangleArray(tr);
    simplex.setBgTetrahedron(bgTetrahedron);

    TransformGroup tgTetrahedron = new TransformGroup();
    tgTetrahedron.addChild(shape);
    tgTetrahedron.addChild(shapeTr);

    bgTetrahedron.addChild(tgTetrahedron);
    spin.addChild(bgTetrahedron);
    return bgTetrahedron;
  }
Example #18
0
  public void createTriangles(
      IfcRoot ifcRootObject, IfcModelInterface ifcModel, TransformGroup buildingTransformGroup)
      throws RenderEngineException {
    RenderEngineInstance instance =
        ifcEngineModel.getInstanceFromExpressId(ifcRootObject.getExpressId());
    RenderEngineInstanceVisualisationProperties instanceInModelling =
        instance.getVisualisationProperties();
    if (instanceInModelling.getPrimitiveCount() != 0) {
      Appearance appearance = appearances.getAppearance(ifcRootObject);
      if (appearance != null) {
        Point3f[] coordinates = new Point3f[instanceInModelling.getPrimitiveCount() * 3];
        Vector3f[] normals = new Vector3f[instanceInModelling.getPrimitiveCount() * 3];
        for (int i = instanceInModelling.getStartIndex();
            i < instanceInModelling.getPrimitiveCount() * 3 + instanceInModelling.getStartIndex();
            i += 3) {
          int offsetIndex = i - instanceInModelling.getStartIndex();
          int i1 = geometry.getIndex(i);
          int i2 = geometry.getIndex(i + 1);
          int i3 = geometry.getIndex(i + 2);

          coordinates[offsetIndex] =
              new Point3f(
                  geometry.getVertex(i1 * 3),
                  geometry.getVertex(i1 * 3 + 1),
                  geometry.getVertex(i1 * 3 + 2));
          coordinates[offsetIndex + 1] =
              new Point3f(
                  geometry.getVertex(i3 * 3),
                  geometry.getVertex(i3 * 3 + 1),
                  geometry.getVertex(i3 * 3 + 2));
          coordinates[offsetIndex + 2] =
              new Point3f(
                  geometry.getVertex(i2 * 3),
                  geometry.getVertex(i2 * 3 + 1),
                  geometry.getVertex(i2 * 3 + 2));

          normals[offsetIndex] =
              new Vector3f(
                  geometry.getNormal(i1 * 3),
                  geometry.getNormal(i1 * 3 + 1),
                  geometry.getNormal(i1 * 3 + 2));
          normals[offsetIndex + 1] =
              new Vector3f(
                  geometry.getNormal(i3 * 3),
                  geometry.getNormal(i3 * 3 + 1),
                  geometry.getNormal(i3 * 3 + 2));
          normals[offsetIndex + 2] =
              new Vector3f(
                  geometry.getNormal(i2 * 3),
                  geometry.getNormal(i2 * 3 + 1),
                  geometry.getNormal(i2 * 3 + 2));
        }
        TriangleArray triangleArray =
            new TriangleArray(
                coordinates.length, GeometryArray.COORDINATES | GeometryArray.NORMALS);
        triangleArray.setCoordinates(0, coordinates);
        triangleArray.setNormals(0, normals);
        Shape3D myShape = new Shape3D(triangleArray, appearance);
        buildingTransformGroup.addChild(myShape);
        myShape.setUserData(ifcRootObject);
      }
    }
  }
Example #19
0
  public WireNode(double len, double rad) {
    //		super(2);
    //
    //		setGeometry(0,Cylinder.makeGeometry(24,rad,len).getIndexedGeometryArray(),0);
    super();
    Shape3D wire = new Shape3D();
    initShape(wire);
    wire.setGeometry(Cylinder.makeGeometry(24, rad, len).getIndexedGeometryArray());
    Appearance app = Node3D.makeAppearance(new Color3f(new Color(154, 105, 0)), .8f, 0.5f, false);
    TransparencyAttributes ta =
        new TransparencyAttributes(
            TransparencyAttributes.NICEST, 0.5f); // app.getTransparencyAttributes();
    // ta.setTransparency(0.5f);
    app.setTransparencyAttributes(ta);
    wire.setAppearance(app);

    mContents.addChild(wire);

    //////////////////////////////////////////////////////////////////////
    /*
    txt = new Text2D("This is a Text2D!!", new Color3f(0.f,0.f,0.f),"SansSerif",70,Font.PLAIN);
    txt.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
    txt.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
    txt.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
    txt.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
    Appearance a = txt.getAppearance();
    a.setCapability(Appearance.ALLOW_TEXTURE_READ);
    a.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
    txt.setAppearance(a);
    TransformGroup bbtg = new TransformGroup();
    bbtg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    Transform3D t = new Transform3D();
    t.setScale(50.);
    bbtg.setTransform(t);
    bbtg.addChild(txt);
    Billboard bb = new Billboard(bbtg,Billboard.ROTATE_ABOUT_POINT,new Point3f(0.f,0.f,0.f));
    bb.setSchedulingBounds(new BoundingSphere(new Point3d(0.,0.,0.), 100.));
    bbtg.addChild(bb);
    mContents.addChild(bbtg);
    */
    ///////////////////////////////////////////////////////////////////////

    Shape3D line = new Shape3D();
    initShape(line);
    // line.setGeometry(sLine);
    Geometry stem =
        teal.render.j3d.geometry.Cylinder.makeGeometry(20, 0.05, 1, 0.5)
            .getIndexedGeometryArray(true);
    line.setGeometry(stem);

    Cone fatcone = new Cone(0.2f, 0.25f);
    Shape3D cone = new Shape3D();
    initShape(cone);
    cone.setGeometry(fatcone.getShape(Cone.BODY).getGeometry());
    cone.addGeometry(fatcone.getShape(Cone.CAP).getGeometry());

    TransformGroup translated_cone = new TransformGroup();
    Transform3D tran = new Transform3D();
    // tran.set( new Vector3f(0.f,0.95f,0.f));
    tran.set(new Vector3f(0.f, 1.f, 0.f));
    translated_cone.addChild(cone);
    translated_cone.setTransform(tran);

    arrow.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    arrow.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    // arrow.addChild(line);
    // arrow.addChild(translated_cone);
    Appearance arrowAppearance =
        Node3D.makeAppearance(new Color3f(new Color(154, 105, 0)), 0.f, 0.f, false);
    line.setAppearance(arrowAppearance);
    cone.setAppearance(arrowAppearance);
    arrow.addChild(line);
    arrow.addChild(translated_cone);

    Transform3D tran2 = new Transform3D();
    // tran2.set(new Vector3f(0.f,-0.5f,0.f));
    tran2.setScale(4.);
    arrow.setTransform(tran2);
    mContents.addChild(arrow);
  }
Example #20
0
  private MyPickResult getMouseIntersection(MouseEvent e, boolean withSnap) {

    MyPickResult myResult = new MyPickResult();

    Point3d closestObjectPos = null;
    Point3d closestMarkPos = null;
    Node closestObject = null;
    Node closestMark = null;

    // 0: closest object; 1: closest mark
    pickCanvas.setShapeLocation(e);
    PickResult[] allResults = null;
    try {
      allResults = pickCanvas.pickAllSorted();
    } catch (AssertionError ex) {
    }
    if (allResults != null) {
      for (PickResult result : allResults) {
        Shape3D s = (Shape3D) result.getNode(PickResult.SHAPE3D);
        if (s != null) { // only pick a Shape3D object
          if (closestObjectPos != null && closestMarkPos != null) {
            break;
          }
          try {
            PickIntersection intersection = result.getClosestIntersection(cameraPos);
            if (!(s.getParent().getParent().getParent() instanceof Mark)
                && !((s.getParent().getParent().getParent() instanceof Marker))) {
              // markdot/markline/label -> TG -> BG -> Mark/Marker
              try {
                closestObjectPos = intersection.getPointCoordinatesVW();
                closestObject = s;
              } catch (NullPointerException ex) {
              }
            } else if ((s.getParent().getParent().getParent() instanceof Mark)) {
              try {
                closestMarkPos = intersection.getPointCoordinatesVW();
                closestMark = s;
              } catch (NullPointerException ex) {
              }
            }
          } catch (NullPointerException ex) {
          }
        }
      }

      Point3d resultPos = null;
      Node resultNode = null;

      if (closestMark != null) {
        resultPos = closestMarkPos; // priority of result -> mark
        resultNode = closestMark;
      } else if (closestObject != null) {
        resultPos = closestObjectPos;
        resultNode = closestObject;
      }

      if (withSnap) { // snap resultPos to correct position

        // start trying to if cursor are inside object bounding sphere
        if ((closestObjectPos != null && bs.intersect(closestObjectPos))
            || closestMarkPos != null && bs.intersect(closestMarkPos)) {

          Point3d closestObjectPos2 = null;
          Point3d closestMarkPos2 = null;
          Node closestObject2 = null;
          Node closestMark2 = null;

          // initiate snap bounds if hasn't been initiated before
          // "snappable" targets to be considered are the ones inside threshold
          if (cursorBound == null) {
            cursorBound = new BoundingSphere(resultPos, CURSOR_THRESHOLD);
          }
          if (thresholdBound == null) {
            thresholdBound = new BoundingSphere(resultPos, SNAP_THRESHOLD);
          }

          // update the bounds
          // only if the cursor is no longer inside current cursor bounds
          if (!cursorBound.intersect(resultPos)) {
            cursorBound.setCenter(resultPos);
            thresholdBound.setCenter(resultPos);
          }

          // snap to nearest point in the list of snap targets
          double nearestDistance = FARTHEST;
          double distance;
          Point3d nearestTarget = null;

          // snap to vertex. all vertexes listed in snapList
          if (snapList.size() > 0) {
            for (Point3d snapTarget : snapList) {
              if (thresholdBound.intersect(snapTarget)) {
                distance = snapTarget.distance(resultPos);
                if (distance < nearestDistance) {
                  nearestDistance = distance;
                  nearestTarget = snapTarget;
                }

                if (nearestTarget != null) {
                  resultPos.set(nearestTarget); // snap!

                  // pick the snapped node
                  Vector3d camToSnapped = new Vector3d();
                  camToSnapped.x = resultPos.x - cameraPos.x;
                  camToSnapped.y = resultPos.y - cameraPos.y;
                  camToSnapped.z = resultPos.z - cameraPos.z;
                  pickCanvas.setShapeRay(cameraPos, camToSnapped);

                  PickResult[] allResultsSnapped = null;
                  try {
                    allResultsSnapped = pickCanvas.pickAllSorted();
                  } catch (AssertionError ex) {
                  }
                  if (allResultsSnapped != null) {
                    for (PickResult result : allResultsSnapped) {
                      Shape3D s = (Shape3D) result.getNode(PickResult.SHAPE3D);
                      if (s != null) { // only pick a Shape3D object
                        if (closestObjectPos2 != null && closestMarkPos2 != null) {
                          break;
                        }
                        try {
                          PickIntersection intersection = result.getClosestIntersection(cameraPos);
                          if (!(s.getParent().getParent().getParent() instanceof Mark)
                              && !((s.getParent().getParent().getParent() instanceof Marker))) {
                            // markdot/markline/label -> TG -> BG -> Mark/Marker
                            try {
                              closestObjectPos2 = intersection.getPointCoordinatesVW();
                              closestObject2 = s;
                            } catch (NullPointerException ex) {
                            }
                          } else if ((s.getParent().getParent().getParent() instanceof Mark)) {
                            try {
                              closestMarkPos2 = intersection.getPointCoordinatesVW();
                              closestMark2 = s;
                            } catch (NullPointerException ex) {
                            }
                          }
                        } catch (NullPointerException ex) {
                        }
                      }
                    }

                    if (closestMark2 != null) {
                      resultPos = closestMarkPos2; // priority of result -> mark
                      resultNode = closestMark2;
                    } else if (closestObject2 != null) {
                      resultPos = closestObjectPos2;
                      resultNode = closestObject2;
                    }
                  }
                }
              }
            }
          }
        }
      }

      myResult.setPoint(resultPos);
      myResult.setNode(resultNode);
    }
    return myResult;
  }