private void updateSide(int index, GeoPointND[] bottomPoints) {
   outputSegmentsTop
       .getElement(index - 1)
       .modifyInputPoints(getTopPoint(index - 1), getTopPoint(index));
   GeoPolygon polygon = outputPolygonsSide.getElement(index - 1);
   GeoPointND[] p = new GeoPointND[4];
   p[0] = bottomPoints[index - 1];
   p[1] = bottomPoints[index];
   p[2] = getTopPoint(index);
   p[3] = getTopPoint(index - 1);
   polygon.setPoints(p, null, false); // don't create segments
   GeoSegmentND[] s = new GeoSegmentND[4];
   s[0] = getBottom().getSegments()[index];
   s[1] = outputSegmentsSide.getElement(index);
   s[2] = outputSegmentsTop.getElement(index);
   s[3] = outputSegmentsSide.getElement(index - 1);
   polygon.setSegments(s);
   polygon.calcArea();
 }
  @Override
  protected void updateOutput(int newBottomPointsLength, GeoPointND[] bottomPoints) {

    // current length of top points
    int nOld = outputPoints.size() + getShift();

    if (newBottomPointsLength > nOld) {

      int length = newBottomPointsLength - nOld;
      outputPoints.augmentOutputSize(length);
      outputPoints.setLabels(null);

      updateOutputPoints();

      // new sides of the prism
      int l = nOld + length;
      for (int i = nOld; i < l; i++) {
        polyhedron.startNewFace();
        polyhedron.addPointToCurrentFace(bottomPoints[i]);
        polyhedron.addPointToCurrentFace(bottomPoints[(i + 1) % l]);
        polyhedron.addPointToCurrentFace(getTopPoint((i + 1) % l));
        polyhedron.addPointToCurrentFace(getTopPoint(i));
        polyhedron.endCurrentFace();
        GeoPolygon3D polygon = polyhedron.createPolygon(i + 1); // i+1 due to top face
        outputPolygonsSide.addOutput(polygon, false);
        outputSegmentsSide.addOutput((GeoSegment3D) polygon.getSegments()[3], false);
        outputSegmentsTop.addOutput((GeoSegment3D) polygon.getSegments()[2], false);
      }
      outputSegmentsSide.setLabels(null);
      outputSegmentsTop.setLabels(null);

      refreshOutput();
    } else if (newBottomPointsLength < nOld) {

      for (int i = newBottomPointsLength; i < bottomPointsLength; i++) {
        outputPoints.getElement(i - getShift()).setUndefined();
      }

      updateOutputPoints();

      // update top side
      outputSegmentsTop
          .getElement(newBottomPointsLength - 1)
          .modifyInputPoints(getTopPoint(newBottomPointsLength - 1), getTopPoint());
      GeoPolygon polygon = getTopFace();
      GeoPointND[] p = new GeoPointND[newBottomPointsLength];
      p[0] = getTopPoint();
      for (int i = 0; i < newBottomPointsLength - 1; i++) p[1 + i] = getTopPoint(i + 1);
      // polygon.setPoints(p,null,false); //don't create segments
      polygon.modifyInputPoints(p);
      polygon.setSegments(outputSegmentsTop.getOutput(new GeoSegment3D[newBottomPointsLength]));
      polygon.calcArea();

      // update last side
      polygon = outputPolygonsSide.getElement(newBottomPointsLength - 1);
      p = new GeoPointND[4];
      p[0] = bottomPoints[newBottomPointsLength - 1];
      p[1] = bottomPoints[0];
      p[2] = getTopPoint();
      p[3] = getTopPoint(newBottomPointsLength - 1);
      polygon.setPoints(p, null, false); // don't create segments
      GeoSegmentND[] s = new GeoSegmentND[4];
      s[0] = getBottom().getSegments()[newBottomPointsLength];
      s[1] = outputSegmentsSide.getElement(newBottomPointsLength);
      s[2] = outputSegmentsTop.getElement(newBottomPointsLength);
      s[3] = outputSegmentsSide.getElement(newBottomPointsLength - 1);
      polygon.setSegments(s);
      polygon.calcArea();

    } else updateOutputPoints();

    if (bottomPointsLength < newBottomPointsLength) {

      // update top side
      updateTop(newBottomPointsLength);

      // update last sides
      for (int i = bottomPointsLength; i < newBottomPointsLength; i++) updateSide(i, bottomPoints);
    }

    bottomPointsLength = newBottomPointsLength;
  }