Пример #1
0
void
avtLineScanQuery::WalkChain1(vtkPolyData *pd, int ptId, int cellId,
                             vtkIntArray *lineids, int lineid, 
                             int &newPtId, int &newCellId)
{
    static vtkIdList *list = vtkIdList::New();
    list->Reset();
    pd->GetCellPoints(cellId, list);
    if (list->GetNumberOfIds() != 2)
    {
        EXCEPTION0(ImproperUseException);
    }

    int id1 = list->GetId(0);
    int id2 = list->GetId(1);
    newPtId = (id1 == ptId ? id2 : id1);
    int seg1, seg2;
    int numMatches = GetCellsForPoint(newPtId, pd, lineids, lineid, seg1, seg2);
    if (numMatches <= 1)
        newCellId = -1;
    else if (numMatches > 2)
    {
        EXCEPTION0(ImproperUseException);
    }
    else
    {
        newCellId = (seg1 == cellId ? seg2 : seg1);
    }
}
Пример #2
0
int 
avtLineScanQuery::WalkChain(vtkPolyData *pd, int ptId, int cellId, 
                            std::vector<bool> &usedPoint,
                            vtkIntArray *lineids, int lineid)
{
    static vtkIdList *list = vtkIdList::New();

    bool haventFoundEnd = true;
    int  curCell = cellId;
    int  curPt   = ptId;

    int  endOfChain = -1;
    int  counter = 0;
    while (haventFoundEnd)
    {
        list->Reset();
        pd->GetCellPoints(curCell, list);
        if (list->GetNumberOfIds() != 2)
        {
            EXCEPTION0(ImproperUseException);
        }

        int id1 = list->GetId(0);
        int id2 = list->GetId(1);
        int newId = (id1 == curPt ? id2 : id1);
        usedPoint[newId] = true;

        int seg1, seg2;
        int numMatches = 
                      GetCellsForPoint(newId, pd, lineids, lineid, seg1, seg2);
        if (numMatches <= 1)
        {
            haventFoundEnd = false;
            endOfChain = newId;
        }
        else if (numMatches > 2)
        {
            // This is an error condition.  It is believed to occur when
            // a line coincides with an edge.  Empirically, it is believed
            // to happen about one time when you cast 100K lines over 90M
            // zones.  So: it doesn't happen often, but it happens enough.
            // In this case, just ignoring the line won't affect statistics.
            haventFoundEnd = false;
            endOfChain = -1;
        }
        else
        {
            curPt = newId;
            curCell = (seg1 == curCell ? seg2 : seg1);
        }
        if (counter++ > 1000000)
        {
            haventFoundEnd = false;
            endOfChain = -1;
        }
    }

    return endOfChain;
}
void
avtAggregateChordLengthDistributionQuery::ExecuteLineScan(vtkPolyData *pd)
{
    vtkIntArray *lineids = (vtkIntArray *) 
                                  pd->GetCellData()->GetArray("avtLineID");
    if (lineids == NULL)
        EXCEPTION0(ImproperUseException);
        
    int npts = pd->GetNumberOfPoints();
    std::vector<bool> usedPoint(npts, false);
    
    pd->BuildLinks();
    pd->BuildCells();

    // When we determine which line segments are on one side of another,
    // we need to examine the other segments.  But we only want to consider
    // segments that are from the same line (i.e. have the same lineid).
    // So we are using this data structure to keep track of which segments
    // come from which line.  (Instead of having to iterate through all the
    // other segments each time we examine a segment.)
    //
    // So why hash?
    // The lines are spread out over many processors.  So proc X may have
    // lines 100,000 - 100,500.  So we either have to have vectors that are
    // way too big (100,500 entries with the first 100,000 empty),
    // or we have to do some clever indexing.  So we are doing
    // some clever indexing.  In this case, hashing.
    int hashSize = 10000;
    std::vector< std::vector<int> >    hashed_lineid_lookup(hashSize);
    std::vector< std::vector<double> > hashed_segment_length(hashSize);

    for (int i = 0 ; i < npts ; i++)
    {
        if (usedPoint[i])
            continue;
        int seg1, seg2;
        int numMatches = GetCellsForPoint(i, pd, lineids, -1, seg1, seg2);
        if (numMatches == 0)
            continue;
        if (numMatches > 2)
        {
            // We found an error condition.  Give up on this line.  This
            // happens infrequently enough that it should not affect our
            // statistics.
            continue;
        }
        int oneSide = i;
        int otherSide = i;
        int lineid = lineids->GetValue(seg1);
        if (numMatches == 1)
        {
            oneSide   = i;
            otherSide = WalkChain(pd, i, seg1, usedPoint, lineids, lineid);
        }
        else if (numMatches == 2)
        {
            oneSide   = WalkChain(pd, i, seg1, usedPoint, lineids, lineid);
            otherSide = WalkChain(pd, i, seg2, usedPoint, lineids, lineid);
        }
        if (oneSide == -1 || otherSide == -1)
        {
            // We found an error condition.  Give up on this line.  This
            // happens infrequently enough that it should not affect our
            // statistics.
            continue;
        }
        double pt1[3];
        double pt2[3];
        pd->GetPoint(oneSide, pt1);
        pd->GetPoint(otherSide, pt2);
        double dist = sqrt((pt2[0]-pt1[0])*(pt2[0]-pt1[0]) + 
                           (pt2[1]-pt1[1])*(pt2[1]-pt1[1]) + 
                           (pt2[2]-pt1[2])*(pt2[2]-pt1[2]));
 
        int hashid = lineid % hashSize;
        hashed_lineid_lookup[hashid].push_back(lineid);
        hashed_segment_length[hashid].push_back(dist);
    }

    for (int i = 0 ; i < hashSize ; i++)
    {
        std::vector<int> already_considered;
        for (int j = 0 ; j < hashed_lineid_lookup[i].size() ; j++)
        {
             bool alreadyDoneLineId = false;
             int  k;
             for (k = 0 ; k < already_considered.size() ; k++)
                 if (hashed_lineid_lookup[i][j] == already_considered[k])
                     alreadyDoneLineId = true;
             if (alreadyDoneLineId)
                 continue;

             int lineid = hashed_lineid_lookup[i][j];
             already_considered.push_back(lineid);
             double length = 0.;
             for (k = j ; k < hashed_lineid_lookup[i].size() ; k++)
             {
                 if (hashed_lineid_lookup[i][k] == lineid)
                     length += hashed_segment_length[i][k];
             }

             int bin = (int)((length-minLength)/(maxLength-minLength) * numBins);
             if (bin < 0)
                 bin = 0;
             if (bin >= numBins)
                 bin = numBins-1;
             numChords[bin]++;
        }
    }
}
void
avtIndividualChordLengthDistributionQuery::ExecuteLineScan(vtkPolyData *pd)
{
    vtkIntArray *lineids = (vtkIntArray *) 
                                  pd->GetCellData()->GetArray("avtLineID");
    if (lineids == NULL)
        EXCEPTION0(ImproperUseException);
        
    int npts = pd->GetNumberOfPoints();
    std::vector<bool> usedPoint(npts, false);
    
    pd->BuildLinks();
    pd->BuildCells();
    for (int i = 0 ; i < npts ; i++)
    {
        if (usedPoint[i])
            continue;
        int seg1, seg2;
        int numMatches = GetCellsForPoint(i, pd, lineids, -1, seg1, seg2);
        if (numMatches == 0)
            continue;
        if (numMatches > 2)
        {
            // We found an error condition.  Give up on this line.  This
            // happens infrequently enough that it should not affect our
            // statistics.
            continue;
        }
        int oneSide = i;
        int otherSide = i;
        int lineid = lineids->GetValue(seg1);
        if (numMatches == 1)
        {
            oneSide   = i;
            otherSide = WalkChain(pd, i, seg1, usedPoint, lineids, lineid);
        }
        else if (numMatches == 2)
        {
            oneSide   = WalkChain(pd, i, seg1, usedPoint, lineids, lineid);
            otherSide = WalkChain(pd, i, seg2, usedPoint, lineids, lineid);
        }
        if (oneSide == -1 || otherSide == -1)
        {
            // We found an error condition.  Give up on this line.  This
            // happens infrequently enough that it should not affect our
            // statistics.
            continue;
        }
        double pt1[3];
        double pt2[3];
        pd->GetPoint(oneSide, pt1);
        pd->GetPoint(otherSide, pt2);
        double dist = sqrt((pt2[0]-pt1[0])*(pt2[0]-pt1[0]) + 
                           (pt2[1]-pt1[1])*(pt2[1]-pt1[1]) + 
                           (pt2[2]-pt1[2])*(pt2[2]-pt1[2]));
        int bin = (int)((dist-minLength) / (maxLength-minLength) * numBins);
        if (bin < 0)
            bin = 0;
        if (bin >= numBins)
            bin = numBins-1;
        numChords[bin]++;
    }
}
void
avtMassDistributionQuery::ExecuteLineScan(vtkPolyData *pd)
{
    vtkIntArray *lineids = (vtkIntArray *) 
                                  pd->GetCellData()->GetArray("avtLineID");
    if (lineids == NULL)
        EXCEPTION0(ImproperUseException);
        
    int npts = pd->GetNumberOfPoints();
    std::vector<bool> usedPoint(npts, false);
    
    vtkDataArray *arr = pd->GetCellData()->GetArray(varname.c_str());

    pd->BuildLinks();
    pd->BuildCells();

    int extraMsg = 100;
    int totalProg = totalNodes * extraMsg;
    int amtPerMsg = npts / extraMsg + 1;
    UpdateProgress(extraMsg*currentNode+2*extraMsg/3, totalProg);
    int lastMilestone = 0;

    for (int i = 0 ; i < npts ; i++)
    {
        if (usedPoint[i])
            continue;
        int seg1 = 0, seg2 = 0;
        int numMatches = GetCellsForPoint(i, pd, lineids, -1, seg1, seg2);
        if (numMatches == 0)
            continue;
        if (numMatches > 2)
        {
            // We found an error condition.  Give up on this line.  This
            // happens infrequently enough that it should not affect our
            // statistics.
            continue;
        }
        int oneSide = i;
        int otherSide = i;
        int lineid = lineids->GetValue(seg1);
        if (numMatches == 1)
        {
            oneSide   = i;
            otherSide = WalkChain(pd, i, seg1, usedPoint, lineids, lineid);
        }
        else if (numMatches == 2)
        {
            oneSide   = WalkChain(pd, i, seg1, usedPoint, lineids, lineid);
            otherSide = WalkChain(pd, i, seg2, usedPoint, lineids, lineid);
        }
        if (oneSide == -1 || otherSide == -1)
        {
            // We found an error condition.  Give up on this line.  This
            // happens infrequently enough that it should not affect our
            // statistics.
            continue;
        }
        double pt1[3];
        double pt2[3];
        pd->GetPoint(oneSide, pt1);
        pd->GetPoint(otherSide, pt2);
        double dist = sqrt((pt2[0]-pt1[0])*(pt2[0]-pt1[0]) + 
                           (pt2[1]-pt1[1])*(pt2[1]-pt1[1]) + 
                           (pt2[2]-pt1[2])*(pt2[2]-pt1[2]));
        int bin = (int)((dist-minLength) / (maxLength-minLength) * numBins);
        if (bin < 0)
            bin = 0;
        if (bin >= numBins)
            bin = numBins-1;
        int curId = oneSide;
        numMatches = GetCellsForPoint(curId, pd, lineids, -1, seg1, seg2);
        int curCell = seg1;
        double curSegMass = 0.;
        while (curId != otherSide)
        {
           double curSegDen = (arr != NULL ? arr->GetTuple1(curCell) : 1.);
           int newPtId, newCellId;
           WalkChain1(pd, curId, curCell, lineids, lineid, 
                      newPtId, newCellId);
           pd->GetPoint(curId, pt1);
           pd->GetPoint(newPtId, pt2);
           double dist = sqrt((pt2[0]-pt1[0])*(pt2[0]-pt1[0]) + 
                              (pt2[1]-pt1[1])*(pt2[1]-pt1[1]) + 
                              (pt2[2]-pt1[2])*(pt2[2]-pt1[2]));
           curSegMass += curSegDen*dist;
           curId = newPtId;
           curCell = newCellId;
           if (curCell == -1 && curId != otherSide)
           {
               debug1 << "INTERNAL ERROR: path could not be reproduced." 
                      << endl;
               break;
           }
        }
        mass[bin] += curSegMass;

        int currentMilestone = (int)(((float) i) / amtPerMsg);
        if (currentMilestone > lastMilestone)
        {
            UpdateProgress((int)(
                        extraMsg*currentNode+2*extraMsg/3.+currentMilestone/3),
                           extraMsg*totalNodes);
            lastMilestone = currentMilestone;
        }
    }
}