@Override
  @SuppressWarnings("unchecked")
  public void compile() {
    super.compile();

    gridSizes = new int[primitive.getGridsCount()];
    maxGridSize = SFGeometryEngine.getMaxGridsSize(primitive, gridSizes);

    int primitivesSize =
        ((quadsGrid.getNu() - 1) * (quadsGrid.getNv() - 1)) << (primitive.isQuad() ? 0 : 1);
    int primitiveIndex = getArray().generateElements(primitivesSize);

    SFValuenf[] samples = new SFValuenf[gridSizes.length];

    indices = (SFRectangularGrid<Integer>[]) (new SFRectangularGrid<?>[gridSizes.length]);

    for (int gridIndex = 0; gridIndex < gridSizes.length; gridIndex++) {

      SFPipelineGrid pipelineGrid = primitive.getGrid(gridIndex);

      int n1 = gridSizes[gridIndex] - 1;
      int width = SFQuadsGrid.getPartitionedSplitsSize(n1, quadsGrid.getNu());
      int height = SFQuadsGrid.getPartitionedSplitsSize(n1, quadsGrid.getNv());

      SFRectangularGrid<Integer> indices = new SFRectangularGrid<Integer>(width, height);
      this.indices[gridIndex] = indices;

      SFArray<SFValuenf> arrayValues = getArray().getPrimitiveData(gridIndex);

      arrayValues.generateElements(width * height);
      samples[gridIndex] = arrayValues.generateSample();
      SFGridEngine.generateIndices(indices);

      if (quadsGrid.isCloseU() || quadsGrid.isCloseV()) {
        SFGridEngine.closeRectangle(
            indices, quadsGrid.isCloseU() ? 1 : 0, quadsGrid.isCloseV() ? 1 : 0);
      }

      SFQuadrilateralGrid<Integer>[] quads =
          SFGridEngine.breakRectangularGrid(indices, pipelineGrid.getN());
      if (pipelineGrid.isTriangular()) {
        SFTriangularGrid<Integer>[] triangles =
            (SFTriangularGrid<Integer>[]) SFGridEngine.sliceQuads(quads);
        SFGridEngine.loadPrimitiveIndices(getArray(), primitiveIndex, gridIndex, triangles);
      } else {
        SFGridEngine.loadPrimitiveIndices(getArray(), primitiveIndex, gridIndex, quads);
      }
    }

    int n1 = maxGridSize - 1;
    float stepn1 = 1.0f / n1;
    this.gridVS = quadsGrid.generatePartitionedSplits(n1, stepn1, quadsGrid.getV_splits());
    this.gridUS = quadsGrid.generatePartitionedSplits(n1, stepn1, quadsGrid.getU_splits());
    values = new SFRectangularGrid<SFValuenf[]>(gridUS.length, gridVS.length);
    for (int i = 0; i < gridUS.length; i++) {
      for (int j = 0; j < gridVS.length; j++) {
        SFValuenf[] samplesList = new SFValuenf[samples.length];
        for (int j2 = 0; j2 < samples.length; j2++) {
          samplesList[j2] = samples[j2].cloneValue();
        }
        values.setValue(j, i, samplesList);
      }
    }
  }