@Override
  public void drawGeometry(Renderer renderer) {

    renderer.setLayer(getLayer()); // +0f for z-fighting with planes
    renderer.getGeometryManager().draw(getGeometryIndex());
    renderer.setLayer(0);
  }
  @Override
  protected void drawSurfaceGeometry(Renderer renderer) {

    renderer.setLayer(getLayer()); // +0f to avoid z-fighting with planes
    renderer.getGeometryManager().draw(getSurfaceIndex());
    renderer.setLayer(0);
  }
  /**
   * draw surfaces to pick them
   *
   * @param renderer opengl context
   */
  public void drawForPickingSurfaces(Renderer renderer) {

    renderer.disableCulling();

    drawListForPickingSurface(renderer, lists[Drawable3D.DRAW_TYPE_SURFACES]);
    drawListForPickingSurface(renderer, lists[Drawable3D.DRAW_TYPE_CLOSED_SURFACES_NOT_CURVED]);

    renderer.enableCulling();

    renderer.setCullFaceFront();
    drawListForPickingSurface(renderer, lists[Drawable3D.DRAW_TYPE_CLOSED_SURFACES_CURVED]);
    renderer.setCullFaceBack();
    drawListForPickingSurface(renderer, lists[Drawable3D.DRAW_TYPE_CLOSED_SURFACES_CURVED]);

    renderer.disableCulling();

    if (containsClippedSurfacesInclLists()) {
      renderer.enableClipPlanesIfNeeded();
      drawListForPickingSurface(renderer, lists[Drawable3D.DRAW_TYPE_CLIPPED_SURFACES]);
      renderer.disableClipPlanesIfNeeded();
    }

    renderer.enableCulling();

    // lists
    for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_LISTS].iterator(); d.hasNext(); ) {
      ((DrawList3D) d.next()).getDrawable3DLists().drawForPickingSurfaces(renderer);
    }
  }
Beispiel #4
0
  @Override
  public void drawGeometryHidden(Renderer renderer) {

    if (!isVisible()) return;

    if (!isGridVisible()) return;

    if (viewDirectionIsParallel) {
      renderer.setDashTexture(Textures.DASH_LONG);
      renderer.getGeometryManager().draw(gridOutlineIndex);
    } else {
      renderer.setDashTexture(Textures.DASH_SHORT);
      renderer.getGeometryManager().draw(gridIndex);
    }
  }
  /**
   * @param renderer GL renderer
   * @param polygon polygon
   * @param pt polygon triangulation
   * @param vertices vertices of the polygon
   * @param verticesLength vertices length (may <> vertices.length due to cache)
   */
  public static final void drawPolygon(
      Renderer renderer,
      GeoPolygon polygon,
      PolygonTriangulation pt,
      Coords[] vertices,
      int verticesLength) {

    Coords n = polygon.getMainDirection();

    pt.clear();

    try {
      // simplify the polygon and check if there are at least 3 points
      // left
      if (pt.updatePoints() > 2) {

        // check if the polygon is convex
        Convexity convexity = pt.checkIsConvex();
        if (convexity != Convexity.NOT) {
          boolean reverse =
              polygon.getReverseNormalForDrawing() ^ (convexity == Convexity.CLOCKWISE);
          renderer.getGeometryManager().drawPolygonConvex(n, vertices, verticesLength, reverse);
        } else {
          // set intersections (if needed) and divide the polygon into
          // non self-intersecting polygons
          pt.setIntersections();

          // convert the set of polygons to triangle fans
          pt.triangulate();

          // compute 3D coords for intersections
          Coords[] verticesWithIntersections =
              pt.getCompleteVertices(vertices, polygon.getCoordSys(), verticesLength);

          // draw the triangle fans
          renderer
              .getGeometryManager()
              .drawTriangleFans(
                  n, verticesWithIntersections, pt.getMaxPointIndex(), pt.getTriangleFans());
        }
      }
    } catch (Exception e) {
      App.debug(e.getMessage());
      e.printStackTrace();
    }
  }
  /**
   * draw the not hidden (solid) parts of curves and points
   *
   * @param renderer opengl context
   */
  public void draw(Renderer renderer) {

    // curves
    for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_CURVES].iterator(); d.hasNext(); ) {
      d.next().drawOutline(renderer);
    }

    if (containsClippedCurves()) {
      renderer.enableClipPlanesIfNeeded();
      for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_CLIPPED_CURVES].iterator();
          d.hasNext(); ) d.next().drawOutline(renderer);
      renderer.disableClipPlanesIfNeeded();
    }

    // lists
    for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_LISTS].iterator(); d.hasNext(); ) {
      ((DrawList3D) d.next()).getDrawable3DLists().draw(renderer);
    }
  }
  /**
   * draw hidden parts not dashed
   *
   * @param renderer
   */
  public final void drawHiddenNotTextured(Renderer renderer) {
    // points TODO hidden aspect ?
    for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_POINTS].iterator(); d.hasNext(); )
      d.next().drawHidden(renderer);

    for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_LISTS].iterator(); d.hasNext(); )
      ((DrawList3D) d.next()).getDrawable3DLists().drawHiddenNotTextured(renderer);

    renderer.resetCenter();
  }
  /**
   * draw the hidden (dashed) parts of curves and points
   *
   * @param renderer opengl context
   */
  public void drawHiddenTextured(Renderer renderer) {

    // curves
    // TODO if there's no surfaces, no hidden part has to be drawn
    // if(!lists[Drawable3D.DRAW_TYPE_SURFACES].isEmpty())
    for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_CURVES].iterator(); d.hasNext(); )
      d.next().drawHidden(renderer);

    if (containsClippedCurves()) {
      renderer.enableClipPlanesIfNeeded();
      for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_CLIPPED_CURVES].iterator();
          d.hasNext(); ) d.next().drawHidden(renderer);
      renderer.disableClipPlanesIfNeeded();
    }

    // lists
    for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_LISTS].iterator(); d.hasNext(); ) {
      ((DrawList3D) d.next()).getDrawable3DLists().drawHiddenTextured(renderer);
    }
  }
  private void updateOutline(Renderer renderer, Coords[] vertices, int length) {

    PlotterBrush brush = renderer.getGeometryManager().getBrush();
    brush.start(getReusableGeometryIndex());
    brush.setThickness(getGeoElement().getLineThickness(), (float) getView3D().getScale());
    for (int i = 0; i < length - 1; i++) {
      brush.setAffineTexture(0.5f, 0.25f);
      brush.segment(vertices[i], vertices[i + 1]);
    }
    brush.setAffineTexture(0.5f, 0.25f);
    brush.segment(vertices[length - 1], vertices[0]);
    setGeometryIndex(brush.end());
  }
  @Override
  public void drawOutline(Renderer renderer) {

    if (isVisible()) {

      setHighlightingColor();

      renderer.getTextures().setDashFromLineType(getGeoElement().getLineType());
      drawGeometry(renderer);
    }

    drawTracesOutline(renderer, false);
  }
  private void drawForPickingPointsAndCurves(Renderer renderer, DrawList3D parent) {

    renderer.disableCulling();

    drawListForPickingPointOrCurve(renderer, lists[Drawable3D.DRAW_TYPE_DEFAULT]);
    drawListForPickingPointOrCurve(renderer, lists[Drawable3D.DRAW_TYPE_POINTS]);
    drawListForPickingPointOrCurve(renderer, lists[Drawable3D.DRAW_TYPE_CURVES]);

    if (containsClippedCurves()) {
      renderer.enableClipPlanesIfNeeded();
      drawListForPickingPointOrCurve(renderer, lists[Drawable3D.DRAW_TYPE_CLIPPED_CURVES]);
      renderer.disableClipPlanesIfNeeded();
    }

    renderer.enableCulling();
    renderer.setCullFaceBack();

    // lists
    for (Iterator<Drawable3D> d = lists[Drawable3D.DRAW_TYPE_LISTS].iterator(); d.hasNext(); ) {
      ((DrawList3D) d.next()).getDrawable3DLists().drawForPickingPointsAndCurves(renderer);
    }
  }
Beispiel #12
0
  @Override
  public void drawGeometry(Renderer renderer) {
    switch (((GeoQuadric3D) getGeoElement()).getType()) {
      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        drawPlanes[0].drawGeometry(renderer);
        drawPlanes[1].drawGeometry(renderer);
        break;
      case GeoQuadricNDConstants.QUADRIC_PLANE:
        drawPlanes[0].drawGeometry(renderer);
        break;

      case GeoQuadricNDConstants.QUADRIC_LINE:
        // not used: see drawOutline() and drawGeometryHidden()
        break;

      default:
        renderer.setLayer(getLayer());
        renderer.getGeometryManager().draw(getSurfaceIndex());
        renderer.setLayer(0);
        break;
    }
  }
  @Override
  protected boolean updateForItSelf() {

    // super.updateForItSelf();

    // creates the polygon
    GeoPolygon polygon = (GeoPolygon) getGeoElement();

    int pointLength = polygon.getPointsLength();

    if (pointLength < 3) { // no polygon
      setSurfaceIndex(-1);
      return true;
    }

    Renderer renderer = getView3D().getRenderer();

    updateVertices(polygon, pointLength);

    // outline
    if (!isPreview && !polygon.wasInitLabelsCalled()) { // no labels for
      // segments
      updateOutline(renderer, vertices, pointLength);
    }

    // surface
    int index = renderer.startPolygons(getReusableSurfaceIndex());

    drawPolygon(renderer, polygon, pt, vertices, pointLength);

    renderer.endPolygons();

    setSurfaceIndex(index);

    return true;
  }
Beispiel #14
0
 private void drawPlate(Renderer renderer) {
   renderer.setLayer(getLayer() - 1f); // -1f for z-fighting with planes
   renderer.getGeometryManager().draw(getSurfaceIndex());
   renderer.setLayer(0);
 }
Beispiel #15
0
  /**
   * update the geometry
   *
   * @return true
   */
  protected boolean updateGeometry() {

    Renderer renderer = getView3D().getRenderer();
    GeoPlane3D geo = (GeoPlane3D) getGeoElement();
    CoordSys coordsys = geo.getCoordSys();

    float xmin1 = (float) geo.getXmin(), xmax1 = (float) geo.getXmax(), xdelta1 = xmax1 - xmin1;
    float ymin1 = (float) geo.getYmin(), ymax1 = (float) geo.getYmax(), ydelta1 = ymax1 - ymin1;

    // plane
    PlotterSurface surface = renderer.getGeometryManager().getSurface();

    surface.start(geo, getReusableSurfaceIndex());

    surface.setU(xmin1, xmax1);
    surface.setNbU(2);
    surface.setV(ymin1, ymax1);
    surface.setNbV(2);

    if (!getView3D().useClippingCube()) {
      float fading;
      fading = xdelta1 * geo.getFading();
      surface.setUFading(fading, fading);
      fading = ydelta1 * geo.getFading();
      surface.setVFading(fading, fading);
    }
    surface.draw();
    setSurfaceIndex(surface.end());

    // grid
    if (isGridVisible()) {

      PlotterBrush brush = renderer.getGeometryManager().getBrush();

      if (hasTrace()) {
        brush.start(-1);
      } else {
        brush.start(gridIndex);
      }
      removeGeometryIndex(gridIndex);
      float thickness =
          brush.setThickness(getGeoElement().getLineThickness(), (float) getView3D().getScale());

      brush.setColor(getGeoElement().getObjectColor());

      double dx = geo.getGridXd();
      geo.getGridYd();
      double dy;
      if (Double.isNaN(dx)) {
        dx = getView3D().getNumbersDistance();
        dy = dx;
      } else {
        dy = geo.getGridYd();
      }

      brush.setAffineTexture((0f - xmin1) / ydelta1, 0.25f);
      int i0 = (int) (ymin1 / dy);
      if (ymin1 > 0) i0++;
      for (int i = i0; i <= ymax1 / dy; i++)
        brush.segment(
            coordsys.getPointForDrawing(xmin1, i * dy), coordsys.getPointForDrawing(xmax1, i * dy));
      // along y axis
      brush.setAffineTexture((0f - ymin1) / xdelta1, 0.25f);
      i0 = (int) (xmin1 / dx);
      if (xmin1 > 0) i0++;
      for (int i = i0; i <= xmax1 / dx; i++)
        brush.segment(
            coordsys.getPointForDrawing(i * dx, ymin1), coordsys.getPointForDrawing(i * dx, ymax1));

      gridIndex = brush.end();

      brush.start(gridOutlineIndex);
      removeGeometryIndex(gridOutlineIndex);

      boolean showClippingCube = getView3D().showClippingCube();

      // draws the rectangle outline
      if (showClippingCube) {
        brush.setAffineTexture((0f - xmin1) / ydelta1, 0.25f);
      } else brush.setPlainTexture();
      brush.segment(
          coordsys.getPointForDrawing(xmin1, ymax1 - thickness),
          coordsys.getPointForDrawing(xmax1, ymax1 - thickness));
      brush.segment(
          coordsys.getPointForDrawing(xmin1, ymin1 + thickness),
          coordsys.getPointForDrawing(xmax1, ymin1 + thickness));

      if (showClippingCube) {
        brush.setAffineTexture((0f - ymin1) / xdelta1, 0.25f);
      }
      brush.segment(
          coordsys.getPointForDrawing(xmin1 + thickness, ymin1),
          coordsys.getPointForDrawing(xmin1 + thickness, ymax1));
      brush.segment(
          coordsys.getPointForDrawing(xmax1 - thickness, ymin1),
          coordsys.getPointForDrawing(xmax1 - thickness, ymax1));

      gridOutlineIndex = brush.end();
    }

    return true;
  }
Beispiel #16
0
  @Override
  protected void updateForView() {

    GeoQuadric3D quadric = (GeoQuadric3D) getGeoElement();
    int type = quadric.getType();

    switch (type) {
      case GeoQuadricNDConstants.QUADRIC_SPHERE:
        if (getView3D().viewChangedByZoom()) {
          Renderer renderer = getView3D().getRenderer();
          PlotterSurface surface = renderer.getGeometryManager().getSurface();

          double s = scale;
          scale = getView3D().getScale();
          // check if longitude length changes
          double radius = quadric.getHalfAxis(0);
          int l = surface.calcSphereLongitudesNeeded(radius, scale);
          // redraw if sphere was not visible, or if new longitude length,
          // or if negative zoom occured
          if (visible == Visible.TOTALLY_OUTSIDE || l != longitude || scale < s) {
            Coords center = quadric.getMidpoint3D();
            checkSphereVisible(center, radius);
            if (visible != Visible.TOTALLY_OUTSIDE) {
              // App.debug(l+","+longitude);
              longitude = l;
              surface.start(getReusableSurfaceIndex());
              drawSphere(surface, center, radius);
              setSurfaceIndex(surface.end());
              recordTrace();
            } else {
              setSurfaceIndex(-1);
            }
          }
        } else if (visible != Visible.TOTALLY_INSIDE && getView3D().viewChangedByTranslate()) {
          Renderer renderer = getView3D().getRenderer();
          PlotterSurface surface = renderer.getGeometryManager().getSurface();

          Coords center = quadric.getMidpoint3D();
          double radius = quadric.getHalfAxis(0);
          checkSphereVisible(center, radius);
          if (visible != Visible.TOTALLY_OUTSIDE) {
            surface.start(getReusableSurfaceIndex());
            drawSphere(surface, center, radius);
            setSurfaceIndex(surface.end());
            recordTrace();
          } else {
            setSurfaceIndex(-1);
          }
        }
        break;
      case GeoQuadricNDConstants.QUADRIC_ELLIPSOID:
      case GeoQuadricNDConstants.QUADRIC_CONE:
      case GeoQuadricNDConstants.QUADRIC_CYLINDER:
      case GeoQuadricNDConstants.QUADRIC_HYPERBOLOID_ONE_SHEET:
      case GeoQuadricNDConstants.QUADRIC_HYPERBOLOID_TWO_SHEETS:
      case GeoQuadricNDConstants.QUADRIC_PARABOLOID:
      case GeoQuadricNDConstants.QUADRIC_HYPERBOLIC_PARABOLOID:
      case GeoQuadricNDConstants.QUADRIC_PARABOLIC_CYLINDER:
      case GeoQuadricNDConstants.QUADRIC_HYPERBOLIC_CYLINDER:
      case GeoQuadricNDConstants.QUADRIC_SINGLE_POINT:
        if (getView3D().viewChangedByZoom() || getView3D().viewChangedByTranslate()) {
          updateForItSelf();
        }
        break;
      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        if (getView3D().viewChanged()) {
          initDrawPlanes(quadric);
          drawPlanes[0].updateForView();
          drawPlanes[1].updateForView();
          super.setWaitForUpdate();
        }
        break;

      case GeoQuadricNDConstants.QUADRIC_PLANE:
        if (getView3D().viewChanged()) {
          initDrawPlanes(quadric);
          drawPlanes[0].updateForView();
          super.setWaitForUpdate();
        }
        break;

      case GeoQuadricNDConstants.QUADRIC_LINE:
        if (getView3D().viewChanged()) {
          initDrawLine(quadric);
          drawLine.updateForView();
          super.setWaitForUpdate();
        }
        break;
    }
  }
Beispiel #17
0
  @Override
  protected boolean updateForItSelf() {

    Renderer renderer = getView3D().getRenderer();
    GeoQuadric3D quadric = (GeoQuadric3D) getGeoElement();
    PlotterSurface surface;
    int type = quadric.getType();

    double min, max;

    switch (type) {
      case GeoQuadricNDConstants.QUADRIC_SPHERE:
        Coords center = quadric.getMidpoint3D();
        double radius = quadric.getHalfAxis(0);
        boundsMin.setValues(center, 3);
        boundsMax.setValues(center, 3);
        boundsMin.addInside(-radius);
        boundsMax.addInside(radius);
        checkSphereVisible(center, radius);
        if (visible != Visible.TOTALLY_OUTSIDE) {
          surface = renderer.getGeometryManager().getSurface();
          surface.start(getReusableSurfaceIndex());
          scale = getView3D().getScale();
          longitude = surface.calcSphereLongitudesNeeded(radius, scale);
          drawSphere(surface, center, radius);
          setSurfaceIndex(surface.end());
        } else {
          setSurfaceIndex(-1);
        }
        break;
      case GeoQuadricNDConstants.QUADRIC_ELLIPSOID:
        center = quadric.getMidpoint3D();
        double r0 = quadric.getHalfAxis(0);
        double r1 = quadric.getHalfAxis(1);
        double r2 = quadric.getHalfAxis(2);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        scale = getView3D().getScale();
        radius = Math.max(r0, Math.max(r1, r2));
        longitude = surface.calcSphereLongitudesNeeded(radius, scale);
        Coords ev0 = quadric.getEigenvec3D(0);
        Coords ev1 = quadric.getEigenvec3D(1);
        Coords ev2 = quadric.getEigenvec3D(2);
        surface.drawEllipsoid(center, ev0, ev1, ev2, r0, r1, r2, longitude);
        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_HYPERBOLOID_ONE_SHEET:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        r2 = quadric.getHalfAxis(2);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev2.mul(r2));
        scale = getView3D().getScale();
        // get radius at max
        radius =
            Math.max(r0, r1)
                * Math.max(Math.abs(vMinMax[0]), Math.max(Math.abs(vMinMax[1]), 1))
                / r2;
        longitude = surface.calcSphereLongitudesNeeded(radius, scale);
        min = DrawConic3D.asinh(vMinMax[0]);
        max = DrawConic3D.asinh(vMinMax[1]);
        surface.drawHyperboloidOneSheet(
            center, ev0, ev1, ev2, r0, r1, r2, longitude, min, max, !getView3D().useClippingCube());
        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_HYPERBOLOID_TWO_SHEETS:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        r2 = quadric.getHalfAxis(2);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev2.mul(r2));
        scale = getView3D().getScale();
        // get radius at max
        radius = Math.max(r0, r1) * Math.max(Math.abs(vMinMax[0]), Math.abs(vMinMax[1])) / r2;
        longitude = surface.calcSphereLongitudesNeeded(radius, scale);
        if (vMinMax[0] < -1) { // bottom exists
          min = -DrawConic3D.acosh(-vMinMax[0]);
        } else if (vMinMax[0] <= 1) { // top ends at pole
          min = 0;
        } else { // top pole is cut
          min = DrawConic3D.acosh(vMinMax[0]);
        }
        if (vMinMax[1] > 1) { // top exists
          max = DrawConic3D.acosh(vMinMax[1]);
        } else if (vMinMax[1] >= -1) { // bottom ends at pole
          max = 0;
        } else { // bottom pole is cut
          max = -DrawConic3D.acosh(-vMinMax[1]);
        }
        surface.drawHyperboloidTwoSheets(
            center, ev0, ev1, ev2, r0, r1, r2, longitude, min, max, !getView3D().useClippingCube());
        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_PARABOLOID:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (quadric.getHalfAxis(2) < 0) {
          ev0 = ev0.mul(-1);
          ev2 = ev2.mul(-1);
        }
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev2);
        if (vMinMax[1] < 0) {
          // nothing to draw
          setSurfaceIndex(surface.end());
        } else {
          scale = getView3D().getScale();
          // get radius at max
          if (vMinMax[0] <= 0) {
            vMinMax[0] = 0;
          } else {
            vMinMax[0] = Math.sqrt(vMinMax[0]);
          }
          vMinMax[1] = Math.sqrt(vMinMax[1]);
          radius = Math.max(r0, r1) * vMinMax[1];
          longitude = surface.calcSphereLongitudesNeeded(radius, scale);
          surface.drawParaboloid(
              center,
              ev0,
              ev1,
              ev2,
              r0,
              r1,
              longitude,
              vMinMax[0],
              vMinMax[1],
              !getView3D().useClippingCube());
          setSurfaceIndex(surface.end());
        }
        break;

      case GeoQuadricNDConstants.QUADRIC_HYPERBOLIC_PARABOLOID:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (uMinMax == null) {
          uMinMax = new double[2];
        }
        uMinMax[0] = Double.POSITIVE_INFINITY;
        uMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(uMinMax, center, ev0);
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev1);
        surface.drawHyperbolicParaboloid(
            center,
            ev0,
            ev1,
            ev2,
            r0,
            r1,
            uMinMax[0],
            uMinMax[1],
            vMinMax[0],
            vMinMax[1],
            !getView3D().useClippingCube());
        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_PARABOLIC_CYLINDER:
        center = quadric.getMidpoint3D();
        r2 = quadric.getHalfAxis(2);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (uMinMax == null) {
          uMinMax = new double[2];
        }
        uMinMax[0] = Double.POSITIVE_INFINITY;
        uMinMax[1] = Double.NEGATIVE_INFINITY;
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev0);
        if (vMinMax[1] < 0) {
          // nothing to draw
          setSurfaceIndex(surface.end());
        } else {
          scale = getView3D().getScale();
          // get radius at max
          if (vMinMax[0] <= 0) {
            vMinMax[0] = 0;
          } else {
            vMinMax[0] = Math.sqrt(vMinMax[0]);
          }
          vMinMax[1] = Math.sqrt(vMinMax[1]);
          getView3D().getMinIntervalOutsideClipping(uMinMax, center, ev1);
          surface.drawParabolicCylinder(
              center,
              ev0,
              ev1,
              ev2,
              r2,
              vMinMax[0],
              vMinMax[1],
              uMinMax[0],
              uMinMax[1],
              !getView3D().useClippingCube());
          setSurfaceIndex(surface.end());
        }
        break;

      case GeoQuadricNDConstants.QUADRIC_HYPERBOLIC_CYLINDER:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (uMinMax == null) {
          uMinMax = new double[2];
        }
        uMinMax[0] = Double.POSITIVE_INFINITY;
        uMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(uMinMax, center, ev0.mul(r0));
        scale = getView3D().getScale();
        if (uMinMax[0] < -1) { // bottom exists
          min = -DrawConic3D.acosh(-uMinMax[0]);
        } else if (uMinMax[0] <= 1) { // top ends at pole
          min = 0;
        } else { // top pole is cut
          min = DrawConic3D.acosh(uMinMax[0]);
        }
        if (uMinMax[1] > 1) { // top exists
          max = DrawConic3D.acosh(uMinMax[1]);
        } else if (uMinMax[1] >= -1) { // bottom ends at pole
          max = 0;
        } else { // bottom pole is cut
          max = -DrawConic3D.acosh(-uMinMax[1]);
        }
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev2);
        if (min < 0) {
          surface.drawHyperbolicCylinder(
              center,
              ev0.mul(-1),
              ev1.mul(-1),
              ev2,
              r0,
              r1,
              -max,
              -min,
              vMinMax[0],
              vMinMax[1],
              !getView3D().useClippingCube());
        }
        if (max > 0) {
          surface.drawHyperbolicCylinder(
              center,
              ev0,
              ev1,
              ev2,
              r0,
              r1,
              min,
              max,
              vMinMax[0],
              vMinMax[1],
              !getView3D().useClippingCube());
        }
        uMinMax[0] = Math.sinh(min);
        uMinMax[1] = Math.sinh(max);
        setSurfaceIndex(surface.end());

        break;

      case GeoQuadricNDConstants.QUADRIC_CONE:
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        if (quadric instanceof GeoQuadric3DPart) { // simple cone
          double height =
              ((GeoQuadric3DPart) quadric).getBottomParameter()
                  - ((GeoQuadric3DPart) quadric).getTopParameter();
          Coords top = quadric.getMidpoint3D();
          ev1 = quadric.getEigenvec3D(0);
          ev2 = quadric.getEigenvec3D(1);
          radius = quadric.getHalfAxis(0);
          double radius2 = quadric.getHalfAxis(1);
          Coords bottomCenter =
              surface.cone(
                  top,
                  ev1,
                  ev2,
                  quadric.getEigenvec3D(2),
                  radius,
                  radius2,
                  0,
                  2 * Math.PI,
                  height,
                  1f);

          boundsMin.setValues(top, 3);
          boundsMax.setValues(top, 3);
          radius *= height;
          enlargeBoundsToDiagonal(boundsMin, boundsMax, bottomCenter, ev1, ev2, radius, radius2);

        } else { // infinite cone
          if (vMinMax == null) {
            vMinMax = new double[2];
          }
          vMinMax[0] = Double.POSITIVE_INFINITY;
          vMinMax[1] = Double.NEGATIVE_INFINITY;
          getMinMax(vMinMax);
          min = vMinMax[0];
          max = vMinMax[1];
          // min -= delta;
          // max += delta;
          // App.debug(min+","+max);
          center = quadric.getMidpoint3D();
          ev1 = quadric.getEigenvec3D(0);
          ev2 = quadric.getEigenvec3D(1);
          Coords ev3 = quadric.getEigenvec3D(2);
          r1 = quadric.getHalfAxis(0);
          r2 = quadric.getHalfAxis(1);

          if (min * max < 0) {
            if (getView3D().useClippingCube()) {
              surface.cone(center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, min, 1f);
              surface.cone(center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, max, 1f);
            } else {
              surface.cone(
                  center,
                  ev1,
                  ev2,
                  ev3,
                  r1,
                  r2,
                  0,
                  2 * Math.PI,
                  min,
                  (float) ((-9 * min - max) / (min - max)));
              surface.cone(
                  center,
                  ev1,
                  ev2,
                  ev3,
                  r1,
                  r2,
                  0,
                  2 * Math.PI,
                  max,
                  (float) ((-9 * max - min) / (max - min)));
            }
          } else {
            if (getView3D().useClippingCube()) {
              surface.cone(center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, min, max, false, false);
            } else {
              double delta = (max - min) / 10;
              surface.cone(
                  center,
                  ev1,
                  ev2,
                  ev3,
                  r1,
                  r2,
                  0,
                  2 * Math.PI,
                  min + delta,
                  max - delta,
                  false,
                  false);
              surface.cone(
                  center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, min, min + delta, true, false);
              surface.cone(
                  center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, max - delta, max, false, true);
            }
          }
        }

        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_CYLINDER:
        center = quadric.getMidpoint3D();
        ev1 = quadric.getEigenvec3D(0);
        ev2 = quadric.getEigenvec3D(1);
        Coords ev3 = quadric.getEigenvec3D(2);

        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());

        if (quadric instanceof GeoQuadric3DPart) { // simple cylinder
          radius = quadric.getHalfAxis(0);
          double radius2 = quadric.getHalfAxis(1);
          longitude = renderer.getGeometryManager().getLongitude(radius, getView3D().getScale());
          Coords bottomCenter =
              surface.cylinder(
                  center,
                  ev1,
                  ev2,
                  ev3,
                  radius,
                  radius2,
                  0,
                  2 * Math.PI,
                  quadric.getMinParameter(1),
                  quadric.getMaxParameter(1),
                  false,
                  false,
                  longitude);

          boundsMin.set(Double.POSITIVE_INFINITY);
          boundsMax.set(Double.NEGATIVE_INFINITY);
          enlargeBoundsToDiagonal(boundsMin, boundsMax, center, ev1, ev2, radius, radius);
          enlargeBoundsToDiagonal(boundsMin, boundsMax, bottomCenter, ev1, ev2, radius, radius);

        } else {
          if (vMinMax == null) {
            vMinMax = new double[2];
          }
          vMinMax[0] = Double.POSITIVE_INFINITY;
          vMinMax[1] = Double.NEGATIVE_INFINITY;
          getMinMax(vMinMax);
          min = vMinMax[0];
          max = vMinMax[1];
          r1 = quadric.getHalfAxis(0);
          r2 = quadric.getHalfAxis(1);
          radius = Math.max(r1, r2);

          longitude = renderer.getGeometryManager().getLongitude(radius, getView3D().getScale());
          if (getView3D().useClippingCube()) {
            surface.cylinder(
                center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, min, max, false, false, longitude);
          } else {
            double delta = (max - min) / 10;
            surface.cylinder(
                center,
                ev1,
                ev2,
                ev3,
                r1,
                r2,
                0,
                2 * Math.PI,
                min + delta,
                max - delta,
                false,
                false,
                longitude);
            surface.cylinder(
                center,
                ev1,
                ev2,
                ev3,
                r1,
                r2,
                0,
                2 * Math.PI,
                min,
                min + delta,
                true,
                false,
                longitude);
            surface.cylinder(
                center,
                ev1,
                ev2,
                ev3,
                r1,
                r2,
                0,
                2 * Math.PI,
                max - delta,
                max,
                false,
                true,
                longitude);
          }
        }

        setSurfaceIndex(surface.end());

        break;

      case GeoQuadricNDConstants.QUADRIC_SINGLE_POINT:
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        Coords m = quadric.getMidpoint3D();
        double thickness =
            quadric.getLineThickness() / getView3D().getScale() * DrawPoint3D.DRAW_POINT_FACTOR;
        surface.drawSphere(quadric.getLineThickness(), m, thickness);
        setSurfaceIndex(surface.end());

        boundsMin.setValues(m, 3);
        boundsMax.setValues(m, 3);
        boundsMin.addInside(-thickness);
        boundsMax.addInside(thickness);
        break;

      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        initDrawPlanes(quadric);
        drawPlanes[0].updateForItSelf();
        drawPlanes[1].updateForItSelf();
        break;

      case GeoQuadricNDConstants.QUADRIC_PLANE:
        initDrawPlanes(quadric);
        drawPlanes[0].updateForItSelf();
        break;

      case GeoQuadricNDConstants.QUADRIC_LINE:
        initDrawLine(quadric);
        drawLine.updateForItSelf();
        break;

      default:
        setSurfaceIndex(-1);
    }

    return true;
  }
 private static void drawListForPickingPointOrCurve(Renderer renderer, Drawable3DList list) {
   for (Iterator<Drawable3D> iter = list.iterator(); iter.hasNext(); ) {
     Drawable3D d = iter.next();
     renderer.pick(d, PickingType.POINT_OR_CURVE);
   }
 }
 private static void drawListForPickingSurface(Renderer renderer, Drawable3DList list) {
   for (Iterator<Drawable3D> iter = list.iterator(); iter.hasNext(); ) {
     Drawable3D d = iter.next();
     renderer.pick(d, PickingType.SURFACE);
   }
 }