Esempio n. 1
0
inline void
ConstructPolyDataHelper(vtkPointData *inPD, vtkCellData *inCD,
     vtkPolyData *output, const vtkSurfaceFromVolume::PointList &pt_list,
     const vtkSurfaceFromVolume::TriangleList &tris,
     int dataType, const PointGetter &pointGetter)
{
    vtkIdType   i, j;

    vtkPointData *outPD = output->GetPointData();
    vtkCellData  *outCD = output->GetCellData();

    vtkIntArray *newOrigNodes = NULL;
    vtkIntArray *origNodes = vtkIntArray::SafeDownCast(
              inPD->GetArray("avtOriginalNodeNumbers"));

    //
    // Set up the output points and its point data.
    //
    vtkPoints *outPts = vtkPoints::New(dataType);
    vtkIdType nOutPts = pt_list.GetTotalNumberOfPoints();
    outPts->SetNumberOfPoints(nOutPts);
    outPD->CopyAllocate(inPD, nOutPts);
    if (origNodes != NULL)
    {
        newOrigNodes = vtkIntArray::New();
        newOrigNodes->SetNumberOfComponents(origNodes->GetNumberOfComponents());
        newOrigNodes->SetNumberOfTuples(nOutPts);
        newOrigNodes->SetName(origNodes->GetName());
    }
    vtkIdType nLists = pt_list.GetNumberOfLists();
    vtkIdType ptIdx = 0;
    for (i = 0 ; i < nLists ; i++)
    {
        const vtkDataSetFromVolume::PointEntry *pe_list = NULL;
        vtkIdType nPts = pt_list.GetList(i, pe_list);
        for (j = 0 ; j < nPts ; j++)
        {
            const vtkDataSetFromVolume::PointEntry &pe = pe_list[j];
            double pt[3], pt1[3], pt2[3];
            pointGetter.GetPoint(pe.ptIds[0], pt1);
            pointGetter.GetPoint(pe.ptIds[1], pt2);
            double p  = pe.percent;
            double bp = 1. - p;
            pt[0] = pt1[0]*p + pt2[0]*bp;
            pt[1] = pt1[1]*p + pt2[1]*bp;
            pt[2] = pt1[2]*p + pt2[2]*bp;
            outPts->SetPoint(ptIdx, pt);
            outPD->InterpolateEdge(inPD, ptIdx, pe.ptIds[0], pe.ptIds[1], bp);
            if (newOrigNodes)
            {
                vtkIdType id = (bp <= 0.5 ? pe.ptIds[0] : pe.ptIds[1]);
                newOrigNodes->SetTuple(ptIdx, origNodes->GetTuple(id));
            }
            ptIdx++;
        }
    }
    output->SetPoints(outPts);
    outPts->Delete();
    if (newOrigNodes)
    {
        // AddArray will overwrite an already existing array with 
        // the same name, exactly what we want here.
        outPD->AddArray(newOrigNodes);
        newOrigNodes->Delete();
    }

    //
    // Now set up the triangles and the cell data.
    //
    vtkIdType ntris = tris.GetTotalNumberOfTriangles();
    vtkIdTypeArray *nlist = vtkIdTypeArray::New();
    nlist->SetNumberOfValues(3*ntris + ntris);
    vtkIdType *nl = nlist->GetPointer(0);

    outCD->CopyAllocate(inCD, ntris);
    vtkIdType cellId = 0;
    vtkIdType nlists = tris.GetNumberOfLists();
    for (i = 0 ; i < nlists ; i++)
    {
        const vtkIdType *list;
        vtkIdType listSize = tris.GetList(i, list);
        for (j = 0 ; j < listSize ; j++)
        {
            outCD->CopyData(inCD, list[0], cellId);
            *nl++ = 3;
            *nl++ = list[1];
            *nl++ = list[2];
            *nl++ = list[3];
            list += 4;
            cellId++;
        }
    }
    vtkCellArray *cells = vtkCellArray::New();
    cells->SetCells(ntris, nlist);
    nlist->Delete();

    output->SetPolys(cells);
    cells->Delete();
}
void
ConstructDataSetHelper(vtkPointData *inPD, vtkCellData *inCD, vtkUnstructuredGrid *output,
    int dataType, vtkIdType numPrevPts, 
    vtkVolumeFromVolume::ShapeList *shapes[8], int nshapes,
    vtkVolumeFromVolume::PointList &pt_list,
    vtkVolumeFromVolume::CentroidPointList &centroid_list,
    const PointGetter &pointGetter)
{
    vtkPointData *outPD = output->GetPointData();
    vtkCellData  *outCD = output->GetCellData();

    vtkIntArray *newOrigNodes = NULL;
    vtkIntArray *origNodes = vtkIntArray::SafeDownCast(
              inPD->GetArray("avtOriginalNodeNumbers"));
    //
    // If the isovolume only affects a small part of the dataset, we can save
    // on memory by only bringing over the points from the original dataset
    // that are used with the output.  Determine which points those are here.
    //
    int *ptLookup = new int[numPrevPts];
    for (vtkIdType i = 0 ; i < numPrevPts ; i++)
        ptLookup[i] = -1;
    int numUsed = 0;
    for (int i = 0 ; i < nshapes ; i++)
    {
        vtkIdType nlists = shapes[i]->GetNumberOfLists();
        int npts_per_shape = shapes[i]->GetShapeSize();
        for (vtkIdType j = 0 ; j < nlists ; j++)
        {
            const vtkIdType *list;
            vtkIdType listSize = shapes[i]->GetList(j, list);
            for (vtkIdType k = 0 ; k < listSize ; k++)
            {
                list++; // skip the cell id entry
                for (vtkIdType l = 0 ; l < npts_per_shape ; l++)
                {
                    int pt = *list;
                    list++;
                    if (pt >= 0 && pt < numPrevPts)
                        if (ptLookup[pt] == -1)
                            ptLookup[pt] = numUsed++;
                }
            }
        }
    }

    //
    // Set up the output points and its point data.
    //
    vtkPoints *outPts = vtkPoints::New(dataType);
    vtkIdType centroidStart = numUsed + pt_list.GetTotalNumberOfPoints();
    vtkIdType nOutPts = centroidStart + centroid_list.GetTotalNumberOfPoints();
    outPts->SetNumberOfPoints(nOutPts);
    outPD->CopyAllocate(inPD, nOutPts);
    if (origNodes != NULL)
    {
        newOrigNodes = vtkIntArray::New();
        newOrigNodes->SetNumberOfComponents(origNodes->GetNumberOfComponents());
        newOrigNodes->SetNumberOfTuples(nOutPts);
        newOrigNodes->SetName(origNodes->GetName());
    }

    //
    // Copy over all the points from the input that are actually used in the
    // output.
    //
    for (vtkIdType i = 0 ; i < numPrevPts ; i++)
    {
        if (ptLookup[i] == -1)
            continue;

        double pt[3];
        pointGetter.GetPoint(i, pt);
        outPts->SetPoint(ptLookup[i], pt);

        outPD->CopyData(inPD, i, ptLookup[i]);
        if (newOrigNodes)
            newOrigNodes->SetTuple(ptLookup[i], origNodes->GetTuple(i));
    }
    vtkIdType ptIdx = numUsed;

    //
    // Now construct all the points that are along edges and new and add 
    // them to the points list.
    //
    vtkIdType nLists = pt_list.GetNumberOfLists();
    for (vtkIdType i = 0 ; i < nLists ; i++)
    {
        const vtkVolumeFromVolume::PointEntry *pe_list = NULL;
        vtkIdType nPts = pt_list.GetList(i, pe_list);
        for (vtkIdType j = 0 ; j < nPts ; j++)
        {
            const vtkVolumeFromVolume::PointEntry &pe = pe_list[j];
            double pt[3], pt1[3], pt2[3];

            pointGetter.GetPoint(pe.ptIds[0], pt1);
            pointGetter.GetPoint(pe.ptIds[1], pt2);

            // Now that we have the original points, calculate the new one.
            double p  = pe.percent;
            double bp = 1. - p;
            pt[0] = pt1[0]*p + pt2[0]*bp;
            pt[1] = pt1[1]*p + pt2[1]*bp;
            pt[2] = pt1[2]*p + pt2[2]*bp;
            outPts->SetPoint(ptIdx, pt);
            outPD->InterpolateEdge(inPD, ptIdx, pe.ptIds[0], pe.ptIds[1], bp);
            if (newOrigNodes)
            {
                vtkIdType id = (bp <= 0.5 ? pe.ptIds[0] : pe.ptIds[1]);
                newOrigNodes->SetTuple(ptIdx, origNodes->GetTuple(id));
            }
            ptIdx++;
        }
    }

    // 
    // Now construct the new "centroid" points and add them to the points list.
    //
    nLists = centroid_list.GetNumberOfLists();
    vtkIdList *idList = vtkIdList::New();
    for (vtkIdType i = 0 ; i < nLists ; i++)
    {
        const vtkVolumeFromVolume::CentroidPointEntry *ce_list = NULL;
        vtkIdType nPts = centroid_list.GetList(i, ce_list);
        for (vtkIdType j = 0 ; j < nPts ; j++)
        {
            const vtkVolumeFromVolume::CentroidPointEntry &ce = ce_list[j];
            idList->SetNumberOfIds(ce.nPts);
            double pts[8][3];
            double weights[8];
            double pt[3] = {0., 0., 0.};
            double weight_factor = 1. / ce.nPts;
            for (int k = 0 ; k < ce.nPts ; k++)
            {
                weights[k] = 1.0 * weight_factor;
                vtkIdType id = 0;
                if (ce.ptIds[k] < 0)
                    id = centroidStart-1 - ce.ptIds[k];
                else if (ce.ptIds[k] >= numPrevPts)
                    id = numUsed + (ce.ptIds[k] - numPrevPts);
                else
                    id = ptLookup[ce.ptIds[k]];
                idList->SetId(k, id);
                outPts->GetPoint(id, pts[k]);
                pt[0] += pts[k][0];
                pt[1] += pts[k][1];
                pt[2] += pts[k][2];
            }
            pt[0] *= weight_factor;
            pt[1] *= weight_factor;
            pt[2] *= weight_factor;

            outPts->SetPoint(ptIdx, pt);
            outPD->InterpolatePoint(outPD, ptIdx, idList, weights);
            if (newOrigNodes)
            {
                // these 'created' nodes have no original designation
                for (int z = 0; z < newOrigNodes->GetNumberOfComponents(); z++)
                    newOrigNodes->SetComponent(ptIdx, z, -1);
            }
            ptIdx++;
        }
    }
    idList->Delete();

    //
    // We are finally done constructing the points list.  Set it with our
    // output and clean up memory.
    //
    output->SetPoints(outPts);
    outPts->Delete();

    if (newOrigNodes)
    {
        // AddArray will overwrite an already existing array with 
        // the same name, exactly what we want here.
        outPD->AddArray(newOrigNodes);
        newOrigNodes->Delete();
    }

    //
    // Now set up the shapes and the cell data.
    //
    vtkIdType cellId = 0;
    vtkIdType nlists;

    vtkIdType ncells = 0;
    vtkIdType conn_size = 0;
    for (int i = 0 ; i < nshapes ; i++)
    {
        vtkIdType ns = shapes[i]->GetTotalNumberOfShapes();
        ncells += ns;
        conn_size += (shapes[i]->GetShapeSize()+1)*ns;
    }

    outCD->CopyAllocate(inCD, ncells);

    vtkIdTypeArray *nlist = vtkIdTypeArray::New();
    nlist->SetNumberOfValues(conn_size);
    vtkIdType *nl = nlist->GetPointer(0);

    vtkUnsignedCharArray *cellTypes = vtkUnsignedCharArray::New();
    cellTypes->SetNumberOfValues(ncells);
    unsigned char *ct = cellTypes->GetPointer(0);

    vtkIdTypeArray *cellLocations = vtkIdTypeArray::New();
    cellLocations->SetNumberOfValues(ncells);
    vtkIdType *cl = cellLocations->GetPointer(0);

    vtkIdType ids[1024]; // 8 (for hex) should be max, but...
    vtkIdType current_index = 0;
    for (int i = 0 ; i < nshapes ; i++)
    {
        const vtkIdType *list;
        nlists = shapes[i]->GetNumberOfLists();
        int shapesize = shapes[i]->GetShapeSize();
        int vtk_type = shapes[i]->GetVTKType();
        for (vtkIdType j = 0 ; j < nlists ; j++)
        {
            int listSize = shapes[i]->GetList(j, list);
            for (vtkIdType k = 0 ; k < listSize ; k++)
            {
                outCD->CopyData(inCD, list[0], cellId);
                for (int l = 0 ; l < shapesize ; l++)
                {
                    if (list[l+1] < 0)
                        ids[l] = centroidStart-1 - list[l+1];
                    else if (list[l+1] >= numPrevPts)
                        ids[l] = numUsed + (list[l+1] - numPrevPts);
                    else
                        ids[l] = ptLookup[list[l+1]];
                }
                list += shapesize+1;
                *nl++ = shapesize;
                *cl++ = current_index;
                *ct++ = vtk_type;
                for (int l = 0 ; l < shapesize ; l++)
                    *nl++ = ids[l];
                current_index += shapesize+1;
                //output->InsertNextCell(vtk_type, shapesize, ids);
                cellId++;
            }
        }
    }

    vtkCellArray *cells = vtkCellArray::New();
    cells->SetCells(ncells, nlist);
    nlist->Delete();

    output->SetCells(cellTypes, cellLocations, cells);
    cellTypes->Delete();
    cellLocations->Delete();
    cells->Delete();

    delete [] ptLookup;
}