void 
TerrainCoverDrawableObject::Render(ModelData & md)
{
	md.points.reserve(points_.size());
	md.points = points_;
	boost::transform(md.points, md.points.begin(), 
		[](const Point3d & p)
	{
		return p + Point3d(0.0f, 0.0f, COVER_Z_SHIFT);
	});

	PointMap ids;
	boost::transform(md.points | boost::adaptors::indexed(0), std::inserter(ids, ids.begin()),
		[](const boost::indexed_range<PointVector>::const_iterator::value_type & val)
	{
		return PointMap::value_type(Point2d::Cast(val.value()), val.index());
	});

	md.indexes = GetTriangulationIndexes(ids);

	NormaleMap normaleMap = GetNormales(md.points, md.indexes);
	md.normales.reserve(points_.size());
	boost::copy(normaleMap | boost::adaptors::map_values, std::back_inserter(md.normales));

	md.textures.reserve(md.points.size());
	boost::transform(md.points, std::back_inserter(md.textures),
		[](const Point3d & p)
	{
		return Point2d::Cast(p);
	});

	md.textureId = TextureId::TransparentGray;
	md.type = ModelData::Mode::Triangle;
}
Esempio n. 2
0
vtkSmartPointer<vtkPolyData> DataDensityFilter::generateOutputData(
    PointMap centralPoints, vtkPointSet* input) {
	vtkSmartPointer<vtkPolyData> output = vtkSmartPointer<vtkPolyData>::New();

	// Create the content of the output poly data object
	vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
	vertices->Allocate(vertices->EstimateSize(1, centralPoints.size()));
	vertices->InsertNextCell(centralPoints.size());

	// Create all arrays from the input data
	QList<vtkSmartPointer<vtkAbstractArray>> inputArrays;
	QList<vtkSmartPointer<vtkAbstractArray>> outputArrays;

	for (int h = 0; h < input->GetPointData()->GetNumberOfArrays(); ++h) {
		vtkSmartPointer<vtkAbstractArray> inputArray = input->GetPointData()->GetAbstractArray(h);

		if (!inputArray) {
			vtkErrorMacro( << "An input array could not be read.");
			return 0;
		}

		vtkSmartPointer<vtkAbstractArray> outputArray = vtkAbstractArray::CreateArray(
		            inputArray->GetDataType());

		outputArray->SetNumberOfComponents(inputArray->GetNumberOfComponents());
		outputArray->SetNumberOfTuples(centralPoints.size());
		outputArray->SetName(inputArray->GetName());

		inputArrays.append(inputArray);
		outputArrays.append(outputArray);
	}
Esempio n. 3
0
void MeaPointTool::SetPosition(const PointMap& points)
{
    // Read the position information from the points
    // map, and set the corresponding point.
    //
    PointMap::const_iterator iter = points.find(_T("1"));
    if (iter != points.end()) {
        m_center = (*iter).second;
    }
        
    // Reposition the tool and update the data display.
    //
    SetPosition();
    Update(NormalUpdate);
}
Esempio n. 4
0
    std::vector<PixelRefPair> pixelateMergeLines(const std::vector<Line>& mergeLines, PointMap& currentMap)
    {
        std::vector<PixelRefPair> mergePixelPairs;

        std::vector<Line>::const_iterator iter = mergeLines.begin(), end =
        mergeLines.end();
        for ( ; iter != end; ++iter )
        {
            const Line & mergeLine = *iter;
            const PixelRef & a = currentMap.pixelate(mergeLine.start(), false);
            const PixelRef & b = currentMap.pixelate(mergeLine.end(), false);

            mergePixelPairs.push_back(PixelRefPair(a, b));
        }
        return mergePixelPairs;
    }
Esempio n. 5
0
void integrateScan(PointMap& pmap, LocalizeMap& lmap, DPose2 offset, double maxrange, double usableRange, const RobotLaser& scan){
  DTransformation2 tp=DTransformation2(offset)*DTransformation2(scan.laserPose)*DTransformation2(scan.laserParams.laserPose);
  
  //robot pose;
  DVector2 rp=tp.translation();
  IVector2 start=lmap.world2map(rp);
  for (int i=0; i<(int)scan.ranges.size(); i++){
    double r=scan.ranges[i];
    if (r>=maxrange)
      continue;
    
    bool cropped=false;
    if (r>usableRange){
      r=usableRange;
      cropped=true;
    }
    static GridLineTraversalLine line;
    DVector2 bp(r,0);
    bp=scan.laserParams.beams[i]*bp;
    bp=tp*bp;;

    IVector2 end=lmap.world2map(bp);

    GridLineTraversal::gridLine(start, end, &line);
    for (int i=0; i<line.num_points; i++){
      lmap.cell(line.points[i]).distance+=1.;
    }
    if (! cropped){
      lmap.cell(end).occupancy+=1.;
      pmap.cell(end)+=bp;
    }
  }
}
Esempio n. 6
0
    std::vector<SimpleLine> getMergedPixelsAsLines(PointMap& currentMap)
    {
        std::vector<SimpleLine> mergedPixelsAsLines;
        std::vector<std::pair<PixelRef, PixelRef>> mergedPixelPairs = currentMap.getMergedPixelPairs();

        std::vector<std::pair<PixelRef, PixelRef>>::const_iterator iter = mergedPixelPairs.begin(), end =
        mergedPixelPairs.end();
        for ( ; iter != end; ++iter )
        {
            std::pair<PixelRef, PixelRef> pixelPair = *iter;
            mergedPixelsAsLines.push_back(SimpleLine(
                                              currentMap.depixelate(pixelPair.first),
                                              currentMap.depixelate(pixelPair.second)
                                              ));
        }
        return mergedPixelsAsLines;
    }
Esempio n. 7
0
    void mergePixelPairs(const std::vector<PixelRefPair>& links, PointMap& currentMap) {

        // check if any link pixel already exists on the map
        std::vector<PixelRefPair>::const_iterator iter = links.begin(), end =
        links.end();
        for ( ; iter != end; ++iter )
        {
            const PixelRefPair link = *iter;

            // check in limits:
            if (!currentMap.includes(link.a) || !currentMap.getPoint(link.a).filled()
                    || !currentMap.includes(link.b) || !currentMap.getPoint(link.b).filled())
            {
                std::stringstream message;
                message << "Line ends not both on painted analysis space (index: "
                        << (iter - links.begin() + 1)
                        << ")" << std::flush;
                throw depthmapX::InvalidLinkException(message.str().c_str());
            }

            // check if we were given coordinates that fall on a previously
            // merged cell, in which case the newest given will replace the
            // oldest and effectively delete the whole link
            if(currentMap.isPixelMerged(link.a)
                    || currentMap.isPixelMerged(link.b))
            {
                // one of the cells is already on the map
                std::stringstream message;
                message << "Link pixel found that is already linked on the map (index: "
                        << (iter - links.begin() + 1)
                        << ")"
                        << std::flush;
                throw depthmapX::InvalidLinkException(message.str().c_str());
            }

            // also check if given links have overlapping pixels:
            std::vector<PixelRefPair>::const_iterator prevIter = links.begin();
            for ( ; prevIter != iter; ++prevIter )
            {
                const PixelRefPair prevLink = *prevIter;

                // PixelRefPair internal == operator only checks a with a and b with b
                // but we also need to check the inverse
                if(link.a == prevLink.a
                        || link.b == prevLink.b
                        || link.a == prevLink.b
                        || link.b == prevLink.a)
                {
                    // one of the cells has already been seen.
                    std::stringstream message;
                    message << "Overlapping link found (index: "
                            << (iter - links.begin() + 1)
                            << ")" << std::flush;
                    throw depthmapX::InvalidLinkException(message.str().c_str());
                }
            }
        }
        std::for_each(links.begin(), links.end(),
                      [&](const PixelRefPair &pair)->void{ currentMap.mergePixels(pair.a,pair.b); });
    }
Esempio n. 8
0
void MeaAngleTool::SetPosition(const PointMap& points)
{
    PointMap::const_iterator iter;
    
    // Read the position information from the points
    // map, and set the corresponding point.
    //
    iter = points.find(_T("1"));
    if (iter != points.end()) {
        m_point1 = (*iter).second;
    }
    iter = points.find(_T("2"));
    if (iter != points.end()) {
        m_point2 = (*iter).second;
    }
    iter = points.find(_T("v"));
    if (iter != points.end()) {
        m_vertex = (*iter).second;
    }
    
    // Reposition the tool and update the data display.
    //
    SetPosition();
    Update(NormalUpdate);
}
Esempio n. 9
0
unsigned long ObjectImpl::addPointNorm(const CTiglPoint& p, const CTiglPoint& n) 
{
    using namespace std;

    //check if point is already in pointlist
    unsigned int index = static_cast<unsigned int>(pointlist.size());
    std::pair<PointMap::iterator,bool> ret;

    ret = pointlist.insert(std::pair<PointImpl, int>(PointImpl(p,n),index));
    index = ret.first->second;
/*#ifndef NDEBUG
    if (ret.second == false) {
        double dist = ret.first->first.dist2(p);
        assert(pointlist.size() == 0 ||  dist < 1e-9);
    }
#endif*/
    if (ret.second == true) {
        // a new point was inserted, we have to keep track
        PointImpl * ptmp = (PointImpl*)&ret.first->first;
        pPoints.push_back(ptmp);
    }
    
    return index;
}
Esempio n. 10
0
Ref<DetectorResult> Detector::detect() {
    Ref<WhiteRectangleDetector> rectangleDetector_(new WhiteRectangleDetector(image_));
    std::vector<Ref<ResultPoint> > ResultPoints = rectangleDetector_->detect();
    Ref<ResultPoint> pointA = ResultPoints[0];
    Ref<ResultPoint> pointB = ResultPoints[1];
    Ref<ResultPoint> pointC = ResultPoints[2];
    Ref<ResultPoint> pointD = ResultPoints[3];

    // Point A and D are across the diagonal from one another,
    // as are B and C. Figure out which are the solid black lines
    // by counting transitions
    std::vector<Ref<ResultPointsAndTransitions> > transitions(4);
    transitions[0].reset(transitionsBetween(pointA, pointB));
    transitions[1].reset(transitionsBetween(pointA, pointC));
    transitions[2].reset(transitionsBetween(pointB, pointD));
    transitions[3].reset(transitionsBetween(pointC, pointD));
    insertionSort(transitions);

    // Sort by number of transitions. First two will be the two solid sides; last two
    // will be the two alternating black/white sides
    Ref<ResultPointsAndTransitions> lSideOne(transitions[0]);
    Ref<ResultPointsAndTransitions> lSideTwo(transitions[1]);

    // Figure out which point is their intersection by tallying up the number of times we see the
    // endpoints in the four endpoints. One will show up twice.
    typedef std::map<Ref<ResultPoint>, int> PointMap;
    PointMap pointCount;
    increment(pointCount, lSideOne->getFrom());
    increment(pointCount, lSideOne->getTo());
    increment(pointCount, lSideTwo->getFrom());
    increment(pointCount, lSideTwo->getTo());

    // Figure out which point is their intersection by tallying up the number of times we see the
    // endpoints in the four endpoints. One will show up twice.
    Ref<ResultPoint> maybeTopLeft;
    Ref<ResultPoint> bottomLeft;
    Ref<ResultPoint> maybeBottomRight;
    for (PointMap::const_iterator entry = pointCount.begin(), end = pointCount.end(); entry != end; ++entry) {
        Ref<ResultPoint> const& point = entry->first;
        int value = entry->second;
        if (value == 2) {
            bottomLeft = point; // this is definitely the bottom left, then -- end of two L sides
        } else {
            // Otherwise it's either top left or bottom right -- just assign the two arbitrarily now
            if (maybeTopLeft == 0) {
                maybeTopLeft = point;
            } else {
                maybeBottomRight = point;
            }
        }
    }

    if (maybeTopLeft == 0 || bottomLeft == 0 || maybeBottomRight == 0) {
        throw NotFoundException();
    }

    // Bottom left is correct but top left and bottom right might be switched
    std::vector<Ref<ResultPoint> > corners(3);
    corners[0].reset(maybeTopLeft);
    corners[1].reset(bottomLeft);
    corners[2].reset(maybeBottomRight);

    // Use the dot product trick to sort them out
    ResultPoint::orderBestPatterns(corners);

    // Now we know which is which:
    Ref<ResultPoint> bottomRight(corners[0]);
    bottomLeft = corners[1];
    Ref<ResultPoint> topLeft(corners[2]);

    // Which point didn't we find in relation to the "L" sides? that's the top right corner
    Ref<ResultPoint> topRight;
    if (!(pointA->equals(bottomRight) || pointA->equals(bottomLeft) || pointA->equals(topLeft))) {
        topRight = pointA;
    } else if (!(pointB->equals(bottomRight) || pointB->equals(bottomLeft)
                 || pointB->equals(topLeft))) {
        topRight = pointB;
    } else if (!(pointC->equals(bottomRight) || pointC->equals(bottomLeft)
                 || pointC->equals(topLeft))) {
        topRight = pointC;
    } else {
        topRight = pointD;
    }

    // Next determine the dimension by tracing along the top or right side and counting black/white
    // transitions. Since we start inside a black module, we should see a number of transitions
    // equal to 1 less than the code dimension. Well, actually 2 less, because we are going to
    // end on a black module:

    // The top right point is actually the corner of a module, which is one of the two black modules
    // adjacent to the white module at the top right. Tracing to that corner from either the top left
    // or bottom right should work here.

    int dimensionTop = transitionsBetween(topLeft, topRight)->getTransitions();
    int dimensionRight = transitionsBetween(bottomRight, topRight)->getTransitions();

    //dimensionTop++;
    if ((dimensionTop & 0x01) == 1) {
        // it can't be odd, so, round... up?
        dimensionTop++;
    }
    dimensionTop += 2;

    //dimensionRight++;
    if ((dimensionRight & 0x01) == 1) {
        // it can't be odd, so, round... up?
        dimensionRight++;
    }
    dimensionRight += 2;

    Ref<BitMatrix> bits;
    Ref<PerspectiveTransform> transform;
    Ref<ResultPoint> correctedTopRight;


    // Rectanguar symbols are 6x16, 6x28, 10x24, 10x32, 14x32, or 14x44. If one dimension is more
    // than twice the other, it's certainly rectangular, but to cut a bit more slack we accept it as
    // rectangular if the bigger side is at least 7/4 times the other:
    if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop) {
        // The matrix is rectangular
        correctedTopRight = correctTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight,
                            dimensionTop, dimensionRight);
        if (correctedTopRight == NULL) {
            correctedTopRight = topRight;
        }

        dimensionTop = transitionsBetween(topLeft, correctedTopRight)->getTransitions();
        dimensionRight = transitionsBetween(bottomRight, correctedTopRight)->getTransitions();

        if ((dimensionTop & 0x01) == 1) {
            // it can't be odd, so, round... up?
            dimensionTop++;
        }

        if ((dimensionRight & 0x01) == 1) {
            // it can't be odd, so, round... up?
            dimensionRight++;
        }

        transform = createTransform(topLeft, correctedTopRight, bottomLeft, bottomRight, dimensionTop,
                                    dimensionRight);
        bits = sampleGrid(image_, dimensionTop, dimensionRight, transform);

    } else {
        // The matrix is square
        int dimension = min(dimensionRight, dimensionTop);

        // correct top right point to match the white module
        correctedTopRight = correctTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension);
        if (correctedTopRight == NULL) {
            correctedTopRight = topRight;
        }

        // Redetermine the dimension using the corrected top right point
        int dimensionCorrected = std::max(transitionsBetween(topLeft, correctedTopRight)->getTransitions(),
                                          transitionsBetween(bottomRight, correctedTopRight)->getTransitions());
        dimensionCorrected++;
        if ((dimensionCorrected & 0x01) == 1) {
            dimensionCorrected++;
        }

        transform = createTransform(topLeft, correctedTopRight, bottomLeft, bottomRight,
                                    dimensionCorrected, dimensionCorrected);
        bits = sampleGrid(image_, dimensionCorrected, dimensionCorrected, transform);
    }

    ArrayRef< Ref<ResultPoint> > points (new Array< Ref<ResultPoint> >(4));
    points[0].reset(topLeft);
    points[1].reset(bottomLeft);
    points[2].reset(correctedTopRight);
    points[3].reset(bottomRight);
    Ref<DetectorResult> detectorResult(new DetectorResult(bits, points));
    return detectorResult;
}
Esempio n. 11
0
DataDensityFilter::PointMap DataDensityFilter::reducePointsKMeans(vtkPointSet* input) {
	// Get the points into the format needed for KMeans
	vtkSmartPointer<vtkTable> inputData = vtkSmartPointer<vtkTable>::New();

	// Create the table needed for the KMeans statistics filter
	for (int c = 0; c < 3; ++c) {
		std::stringstream colName;
		colName << "coord " << c;
		vtkSmartPointer<vtkDoubleArray> doubleArray =
		    vtkSmartPointer<vtkDoubleArray>::New();
		doubleArray->SetNumberOfComponents(1);
		doubleArray->SetName(colName.str().c_str());
		doubleArray->SetNumberOfTuples(input->GetNumberOfPoints());

		for (int r = 0; r < input->GetNumberOfPoints(); ++r) {
			double p[3];
			input->GetPoint(r, p);
			doubleArray->SetValue(r, p[c]);
		}
		inputData->AddColumn(doubleArray);
	}

	// Actually do the KMeans to calculate the centroids for the clusters
	vtkSmartPointer<vtkKMeansStatistics> kMeansStatistics =
	    vtkSmartPointer<vtkKMeansStatistics>::New();

	kMeansStatistics->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, inputData);
	kMeansStatistics->SetColumnStatus(inputData->GetColumnName(0), 1);
	kMeansStatistics->SetColumnStatus(inputData->GetColumnName(1), 1);
	kMeansStatistics->SetColumnStatus(inputData->GetColumnName(2), 1);
	kMeansStatistics->RequestSelectedColumns();

	// Set the default number of clusters to the number of points that should be kept
	kMeansStatistics->SetDefaultNumberOfClusters(std::max(int((1 - this->dataPercentage) *
	        input->GetNumberOfPoints()), 1));

	// Make the filter only do one iteration for a better performance since we do not need a precise kMeans approximation
	kMeansStatistics->SetMaxNumIterations(1);
	kMeansStatistics->SetAssessOption(true);
	kMeansStatistics->Update();

	// Extract the calculated cluster centers from the filter
	vtkSmartPointer<vtkPoints> centroids =
	    vtkSmartPointer<vtkPoints>::New();

	vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast(
	        kMeansStatistics->GetOutputDataObject(vtkStatisticsAlgorithm::OUTPUT_MODEL));
	vtkSmartPointer<vtkTable> outputMeta = vtkTable::SafeDownCast(outputMetaDS->GetBlock(0));

	vtkDoubleArray* coord0 = vtkDoubleArray::SafeDownCast(outputMeta->GetColumnByName("coord 0"));
	vtkDoubleArray* coord1 = vtkDoubleArray::SafeDownCast(outputMeta->GetColumnByName("coord 1"));
	vtkDoubleArray* coord2 = vtkDoubleArray::SafeDownCast(outputMeta->GetColumnByName("coord 2"));

	PointMap outputMap;

	// Put the centroids into the map
	for (int i = 0; i < coord0->GetNumberOfTuples(); ++i) {
		PointCoordinates centroidCoordinates(coord0->GetValue(i), coord1->GetValue(i), coord2->GetValue(i));
		QList<int> subordinatePoints;

		// Extract the point IDs in the centroid's bucket
		for (int r = 0; r < kMeansStatistics->GetOutput()->GetNumberOfRows(); ++r) {
			vtkVariant v = kMeansStatistics->GetOutput()->GetValue(r,
			               kMeansStatistics->GetOutput()->GetNumberOfColumns() - 1);
			if (v.ToInt() == i) {
				subordinatePoints.append(r);
			}
		}
		outputMap.insert(std::make_pair(centroidCoordinates, subordinatePoints));
	}

	return outputMap;
}
Esempio n. 12
0
DataDensityFilter::PointMap DataDensityFilter::reducePointsSimple(vtkPointSet* input) {
	int numberOfPoints = input->GetNumberOfPoints();
	PointMap outputMap;

	// Get the width, height and depth of the data in order to set the absoprtion distance
	double bounds[6];
	input->GetBounds(bounds);

	double minX = bounds[0];
	double maxX = bounds[1];
	double minY = bounds[2];
	double maxY = bounds[3];
	double minZ = bounds[4];
	double maxZ = bounds[5];
	double width = maxX - minX;
	double height = maxY - minY;
	double depth = maxZ - minZ;

	double absorptionDistance = this->dataPercentage * (width + height + depth);

	// This data structure maps a point index to a boolean flag denoting whether it has been absorped by a central point or has become a central point
	std::map<int, bool> pointAbsorptionStatus;

	// In the beginning all points are unabsorbed
	for (int i = 0; i < numberOfPoints; ++i) {
		pointAbsorptionStatus[i] = false;
	}

	QMap<PointCoordinates, int> indices;

	// Generate central points and assign close points to them
	for (int i = 0; i < numberOfPoints; ++i) {
		if (pointAbsorptionStatus[i] == false) {
			double centralPointCoordinatesArray[3];
			input->GetPoint(i, centralPointCoordinatesArray);

			PointCoordinates centralPointCoordinates(centralPointCoordinatesArray[0],
			        centralPointCoordinatesArray[1], centralPointCoordinatesArray[2]);
			QList<int> subordinatePointIndices;
			pointAbsorptionStatus[i] = true;

			indices[centralPointCoordinates] = i;

			for (int j = 0; j < numberOfPoints; ++j) {
				if (pointAbsorptionStatus[j] == false) {
					double subordinatePointCoordinatesArray[3];
					input->GetPoint(j, subordinatePointCoordinatesArray);
					PointCoordinates subordinatePointCoordinates(subordinatePointCoordinatesArray[0],
					        subordinatePointCoordinatesArray[1], subordinatePointCoordinatesArray[2]);

					if (centralPointCoordinates.getDistanceTo(subordinatePointCoordinates) < absorptionDistance) {
						subordinatePointIndices.append(j);
						pointAbsorptionStatus[j] = true;
					}
				}
			}
			outputMap[centralPointCoordinates] = subordinatePointIndices;
		}
	}

	typedef PointMap::iterator it_type;
	for (it_type iterator = outputMap.begin(); iterator != outputMap.end(); iterator++) {
		this->centroidIndices.append(indices[iterator->first]);
	}

	return outputMap;
}