@Override
  public void setWaitForUpdateVisualStyle() {

    GeoQuadric3D quadric = (GeoQuadric3D) getGeoElement();
    switch (quadric.getType()) {
      case GeoQuadricNDConstants.QUADRIC_SINGLE_POINT:
        super.setWaitForUpdate();
        break;
      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        initDrawPlanes(quadric);
        drawPlanes[0].setWaitForUpdateVisualStyle();
        drawPlanes[1].setWaitForUpdateVisualStyle();
        super.setWaitForUpdate();
        break;

      case GeoQuadricNDConstants.QUADRIC_PLANE:
        initDrawPlanes(quadric);
        drawPlanes[0].setWaitForUpdateVisualStyle();
        super.setWaitForUpdate();
        break;

      case GeoQuadricNDConstants.QUADRIC_LINE:
        initDrawLine(quadric);
        drawLine.setWaitForUpdateVisualStyle();
        super.setWaitForUpdate();
        break;
    }

    super.setWaitForUpdateVisualStyle();
  }
  @Override
  public void setWaitForUpdateVisualStyle() {
    super.setWaitForUpdateVisualStyle();

    // also update for plane clip
    setWaitForUpdate();
  }
  @Override
  public void setWaitForReset() {

    gridIndex = -1;
    gridOutlineIndex = -1;
    super.setWaitForReset();
  }
  @Override
  public void setWaitForUpdate() {

    super.setWaitForUpdate();
    setMinMax();
    checkViewDirectionIsParallel();
  }
  @Override
  protected void recordTrace() {
    GeoQuadric3D quadric = (GeoQuadric3D) getGeoElement();
    switch (quadric.getType()) {
      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        initDrawPlanes(quadric);
        drawPlanes[0].recordTrace();
        drawPlanes[1].recordTrace();
        break;

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

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

      default:
        super.recordTrace();
        break;
    }
  }
  @Override
  protected void drawTracesTranspSurface(Renderer renderer) {
    if (drawPlanes != null) {
      drawPlanes[0].drawTracesTranspSurface(renderer);
      if (drawPlanes[1] != null) {
        drawPlanes[1].drawTracesTranspSurface(renderer);
      }
    }

    super.drawTracesTranspSurface(renderer);
  }
  @Override
  protected void clearTraceForViewChanged() {

    if (drawPlanes != null) {
      drawPlanes[0].clearTraceForViewChanged();
      if (drawPlanes[1] != null) {
        drawPlanes[1].clearTraceForViewChanged();
      }
    }

    if (drawLine != null) {
      drawLine.clearTraceForViewChanged();
    }

    super.clearTraceForViewChanged();
  }
  @Override
  public void disposePreview() {

    // first update preview to ensure segments arrays are correct
    updatePreview();

    super.disposePreview();

    // dispose segments
    if (segments != null) {
      for (DrawSegment3D s : segments) {
        s.disposePreview();
      }
    }

    // we may reuse it
    if (segmentsPoints != null) {
      segmentsPoints.clear();
    }
  }
  @Override
  protected void updateColors() {
    super.updateColors();

    GeoQuadric3D quadric = (GeoQuadric3D) getGeoElement();
    switch (quadric.getType()) {
      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        initDrawPlanes(quadric);
        drawPlanes[0].updateColors();
        drawPlanes[1].updateColors();
        break;

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

      case GeoQuadricNDConstants.QUADRIC_LINE:
        initDrawLine(quadric);
        drawLine.updateColors();
        break;
    }
  }
  @Override
  public void setWaitForUpdate() {

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

    switch (type) {
      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        initDrawPlanes(quadric);
        drawPlanes[0].setWaitForUpdate();
        drawPlanes[1].setWaitForUpdate();
        break;
      case GeoQuadricNDConstants.QUADRIC_PLANE:
        initDrawPlanes(quadric);
        drawPlanes[0].setWaitForUpdate();
        break;
      case GeoQuadricNDConstants.QUADRIC_LINE:
        initDrawLine(quadric);
        drawLine.setWaitForUpdate();
        break;
    }
  }
 @Override
 public void removeFromDrawable3DLists(Drawable3DLists lists) {
   removeFromDrawable3DLists(lists, DRAW_TYPE_CURVES);
   super.removeFromDrawable3DLists(lists);
 }
 @Override
 public void addToDrawable3DLists(Drawable3DLists lists) {
   addToDrawable3DLists(lists, DRAW_TYPE_CURVES);
   super.addToDrawable3DLists(lists);
 }
  @Override
  public void drawHidden(Renderer renderer) {
    super.drawHidden(renderer);

    drawTracesOutline(renderer, true);
  }
  @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;
    }
  }