Beispiel #1
0
/*!
  \brief Add linestring to a ring (private)

  \param[in,out] papoRing list of rings
  \param poLine pointer to linestring to be added to a ring 

  \return TRUE on success
  \return FALSE on failure
*/
bool IVFKDataBlock::AppendLineToRing(PointListArray *papoRing, const OGRLineString *poLine, bool bNewRing)
{
    OGRPoint *poFirst, *poLast;
    OGRPoint *poFirstNew, *poLastNew;

    OGRPoint  pt;
    PointList poList;

    /* OGRLineString -> PointList */
    for (int i = 0; i < poLine->getNumPoints(); i++) {
        poLine->getPoint(i, &pt);
        poList.push_back(pt);
    }

    /* create new ring */
    if (bNewRing) {
        papoRing->push_back(new PointList(poList));
        return TRUE;
    }
    
    poFirstNew = &(poList.front());
    poLastNew  = &(poList.back());
    for (PointListArray::const_iterator i = papoRing->begin(), e = papoRing->end();
         i != e; ++i) {
        PointList *ring = (*i);
        poFirst = &(ring->front());
        poLast  = &(ring->back());
        if (!poFirst || !poLast || poLine->getNumPoints() < 2)
            return FALSE;

        if (poFirstNew->Equals(poLast)) {
            /* forward, skip first point */
            ring->insert(ring->end(), poList.begin()+1, poList.end());
            return TRUE;
        }
        
        if (poFirstNew->Equals(poFirst)) {
            /* backward, skip last point */
            ring->insert(ring->begin(), poList.rbegin(), poList.rend()-1);
            return TRUE;
        }
        
        if (poLastNew->Equals(poLast)) {
            /* backward, skip first point */
            ring->insert(ring->end(), poList.rbegin()+1, poList.rend());
            return TRUE;
        }
        
        if (poLastNew->Equals(poFirst)) {
            /* forward, skip last point */
            ring->insert(ring->begin(), poList.begin(), poList.end()-1);
            return TRUE;
        }
    }

    return FALSE;
}
Beispiel #2
0
GLuint CreateSplat(GLuint quadVao, PointList positions)
{
    const int Size = 64;

    Surface surface = CreateVolume(Size, Size, Size);
    GLuint program = CreateProgram("Splat.VS", "Splat.GS", "Splat.FS");
    glUseProgram(program);

    GLint inverseSize = glGetUniformLocation(program, "InverseSize");
    glUniform1f(inverseSize, 1.0f / (float) Size);

    const float innerScale = 0.4f;

    GLint inverseVariance = glGetUniformLocation(program, "InverseVariance");
    glUniform1f(inverseVariance, -1.0f / (2.0f * innerScale * innerScale));

    GLint normalizationConstant = glGetUniformLocation(program, "NormalizationConstant");
    glUniform1f(normalizationConstant, 1.0f / std::pow(std::sqrt(TwoPi) * innerScale, 3.0f));

    glBindFramebuffer(GL_FRAMEBUFFER, surface.FboHandle);
    glBindTexture(GL_TEXTURE_3D, 0);
    glViewport(0, 0, Size, Size);
    glBindVertexArray(quadVao);
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);

    PointList::const_iterator i = positions.begin();
    for (; i != positions.end(); ++i) {

        PointList::const_iterator next = i;
        if (++next == positions.end())
            next = positions.begin();
        VectorMath::Vector3 velocity = (*next - *i);

        GLint center = glGetUniformLocation(program, "Center");
        glUniform4f(center, i->getX(), i->getY(), i->getZ(), 0);

        GLint color = glGetUniformLocation(program, "Color");
        glUniform3fv(color, 1, (float*) &velocity);

        glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, Size);
    }

    PezCheckCondition(GL_NO_ERROR == glGetError(), "Unable to create splat.");
    
    glViewport(0, 0, PEZ_VIEWPORT_WIDTH, PEZ_VIEWPORT_HEIGHT);
    glDisable(GL_BLEND);
    
    return surface.TextureHandle[0];
}
FrontierList Planner::getFrontiers(GridMap* map, GridPoint start)
{
	// Initialization
	mFrontierCellCount = 0;
	mFrontierCount = 0;
	GridMap plan = GridMap(map->getWidth(), map->getHeight());
	FrontierList result;
	
	// Initialize the queue with the robot position
	Queue queue;
	queue.insert(Entry(0, start));
	plan.setData(start, VISIBLE);
	
	// Do full search with weightless Dijkstra-Algorithm
	while(!queue.empty())
	{		
		// Get the nearest cell from the queue
		Queue::iterator next = queue.begin();
		int distance = next->first;
		GridPoint point = next->second;
		queue.erase(next);
		
		// Add neighbors
		bool isFrontier = false;
		PointList neighbors = getNeighbors(point, false);
        char c = 0;
		for(PointList::const_iterator cell = neighbors.begin(); cell < neighbors.end(); cell++)
		{   
            if(map->getData(*cell,c) && c == UNKNOWN)
            {
                plan.setData(*cell, OBSTACLE);
                isFrontier = true;
                break;
            }
            if(map->getData(*cell, c) && c == VISIBLE && 
                plan.getData(*cell, c) && c == UNKNOWN)
            {
                queue.insert(Entry(distance+1, *cell));
                plan.setData(*cell, VISIBLE);
            }
		}
		
		if(isFrontier)
		{
			result.push_back(getFrontier(map, &plan, point));
		}
	}
	
	// Set result message and return the point list
	if(result.size() > 0)
	{
		mStatus = SUCCESS;
		sprintf(mStatusMessage, "Found %d frontiers with %d frontier cells.", mFrontierCount, mFrontierCellCount);
	}else
	{
		mStatus = NO_GOAL;
		sprintf(mStatusMessage, "No reachable frontiers found.");
	}
	return result;
}
void RenderCallback()
{
	// Clear buffers
	glClearColor(1.0f,1.0f,1.0f,1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPointSize(1.0);

	glColor3f(0,0,0);
	glLineWidth(2.0f);
	int i, j;
	glBegin(GL_LINES);
	//渲染凸多边形P
	for( i = gN - 1, j = 0 ; j < gN ; i = j, j += 1 )
	{
		glVertex2f(gP[i].x,gP[i].y);
		glVertex2f(gP[j].x,gP[j].y);
	}
	//渲染凸多边形Q
	for( i = gM - 1, j = 0 ; j < gM ; i = j, j += 1 )
	{
		glVertex2f(gQ[i].x,gQ[i].y);
		glVertex2f(gQ[j].x,gQ[j].y);
	}

	PointList::iterator it;
	for( it = gInterList.begin() ; it != gInterList.end() ; it ++ )
	{
		glVertex2f((*it).x,(*it).y - 20);
		glVertex2f((*it).x,(*it).y + 20);
	}
	glEnd();
	glutSwapBuffers();
}
Beispiel #5
0
    void draw_hand_trace(sf::RenderWindow& window,
                         const PointList& pointList,
                         const sf::Color& color,
                         const float depthScale)
    {
        if (pointList.size() < 2) { return; }

        const float thickness = 4;
        auto it = pointList.begin();
        astra::Vector2i previousPoint = *it;

        while (it != pointList.end())
        {
            const astra::Vector2i currentPoint = *it;
            ++it;

            const sf::Vector2f p1((previousPoint.x + .5f) * depthScale,
                                  (previousPoint.y + .5f) * depthScale);
            const sf::Vector2f p2((currentPoint.x + .5f) * depthScale,
                                  (currentPoint.y + .5f) * depthScale);
            previousPoint = currentPoint;

            window.draw(sfLine(p1, p2, color, thickness));
        }
    }
Beispiel #6
0
 void Dataset<D, ELEM_TYPE>::load(const PointList& newPoints)
 {
     // Pre-allocate memory in one sys call
     m_points.reserve(m_points.size() + newPoints.size());
     // Append given points to end of current point list
     m_points.insert(m_points.end(), newPoints.begin(), newPoints.end());
 }
void Planner::setCoverageMap(PointList points, char value)
{
	PointList::iterator i;
	for(i = points.begin(); i < points.end(); i++)
	{
		mCoverageMap->setData(*i, value);
	}
}
Beispiel #8
0
void handleDual(Hyperbola_segment_2 hs, std::vector<PointList>& polylines)
{
        PointList p;
        hs.generate_points(p);
        PointList points;
        points.insert(points.end(), p.begin(), p.end());
        polylines.push_back(points);
}
Beispiel #9
0
void handleDual(Hyperbola_ray_2 hr, Iso_rectangle_2 crect, std::vector<PointList>& polylines)
{
        PointList p;
        hr.generate_points(p);
        PointList points;
        points.insert(points.end(), p.begin(), p.end());
        polylines.push_back(points);
}
void Planner::addReading(Pose p)
{
    PointList points = willBeExplored(p);
    for(PointList::iterator i = points.begin(); i < points.end(); ++i)
    {
        mCoverageMap->setData(*i, VISIBLE);
    }
}
void pushToFarPlane(PointList& points)
{
    for(PointList::iterator itr=points.begin();
        itr!=points.end();
        ++itr)
    {
        itr->second.z() = 1.0f;
    }
}
void transform(const PointList& in,PointList& out,const osg::Matrix& matrix)
{
    for(PointList::const_iterator itr=in.begin();
        itr!=in.end();
        ++itr)
    {
        out.push_back(Point(itr->first,itr->second * matrix));
    }
}
void transform(PointList& points,const osg::Matrix& matrix)
{
    for(PointList::iterator itr=points.begin();
        itr!=points.end();
        ++itr)
    {
        itr->second = itr->second*matrix;
    }
}
Beispiel #14
0
PointList Board::removeDuplicates(PointList lst) const {
	PointList res;
	for (auto pt : lst) {
		if (std::find(res.begin(), res.end(), pt) == res.end()) {
			res.push_back(pt);
		}
	}
	return res;
}
Beispiel #15
0
PointList::PointList (const PointList&  pointList):
    KKQueue<Point> (true)
{
  PointList::const_iterator  idx;
  for  (idx = pointList.begin ();  idx != pointList.end ();  idx++)
  {
    PushOnBack (new Point (*(*idx)));
  }
}
void copyPointListToVertexList(const PointList& in,VertexList& out)
{
    out.reserve(in.size());
    for(PointList::const_iterator itr=in.begin();
        itr!=in.end();
        ++itr)
    {
        out.push_back(itr->second);
    }
}
Beispiel #17
0
ScreenCalibrator::PickResult ScreenCalibrator::pickPoint(const Ray& queryRay) const
	{
	/* Create a ray picker: */
	Geometry::RayPicker<Scalar,3> picker(queryRay,Scalar(Vrui::getRayPickCosine()));
	
	/* Process all points: */
	for(PointList::const_iterator pIt=trackingPoints.begin();pIt!=trackingPoints.end();++pIt)
		picker(*pIt);
	for(PointList::const_iterator pIt=floorPoints.begin();pIt!=floorPoints.end();++pIt)
		picker(*pIt);
	for(PointList::const_iterator pIt=screenPoints.begin();pIt!=screenPoints.end();++pIt)
		picker(*pIt);
	for(PointList::const_iterator pIt=ballPoints.begin();pIt!=ballPoints.end();++pIt)
		picker(*pIt);
	
	/* Return the index of the picked point: */
	if(picker.havePickedPoint())
		return picker.getPickIndex();
	else
		return ~PickResult(0);
	}
Beispiel #18
0
void handleDual(Hyperbola_ray_2 hr, Iso_rectangle_2 crect, std::vector<PointList>& polylines)
{
        std::cerr << "hyperbola ray" << std::endl; // hr.draw(str);
        PointList p;
        hr.generate_points(p);
        PointList points;
        points.insert(points.end(), p.begin(), p.end());
        polylines.push_back(points);
        for (unsigned int i = 0; i < p.size() - 1; i++) {
          Segment_2 seg(p[i], p[i+1]);
          // doing nothing here
        }
}
Beispiel #19
0
 boost::optional<Point> fastFilterPointList(
         const PointList& pointList,
         std::vector<Point>& newPointList) const
 {
     assert(!pointList.empty());
     newPointList.reserve(pointList.size() - 1);
     std::copy(
             ++pointList.begin(),
             pointList.end(),
             std::back_inserter(newPointList)
             );
     return boost::optional<Point>(pointList.front());
 } // fastFilterFunctorList
Beispiel #20
0
void handleDual(Hyperbola_segment_2 hs, std::vector<PointList>& polylines)
{
        std::cerr << "hyperbola segment" << std::endl; //hs.draw(str);
        PointList p;
        hs.generate_points(p);
        std::cerr << "# hyperbola points: " << p.size() << std::endl;
        PointList points;
        points.insert(points.end(), p.begin(), p.end());
        polylines.push_back(points);
        for (unsigned int i = 0; i < p.size() - 1; i++) {
          Segment_2 seg(p[i], p[i+1]);
          // doing nothing here
        }
}
Beispiel #21
0
// True if a track segment could be placed in its present location
bool Editor::can_place_track(ITrackSegmentPtr track)
{
   PointList covered;
   track->get_endpoints(covered);
   track->get_covers(covered);

   for (auto it = covered.begin(); it != covered.end(); ++it) {
      if (map->is_valid_track(*it)) {
         warn() << "Cannot place track here";
         return false;
      }
   }

   return true;
}
Beispiel #22
0
	PointList ClusteredDatasetGenerator::generate(unsigned int numDimensions,
		const std::vector<ClusterSpecification>& clusters) const
	{
		PointList points;

		RandomPointGenerator rpGenerator;
		for (std::vector<ClusterSpecification>::const_iterator it = clusters.begin();
			(it != clusters.end()); it++)
		{
			PointList clusterPoints = rpGenerator.generatePointsInRegion(
				numDimensions, it->region(), it->numPoints());
			points.insert(points.end(), clusterPoints.begin(), clusterPoints.end());
		}

		return points;
	}
bool Planner::isFrontierCell(GridMap* map, GridPoint point) const
{
    char c = 0;
	if(map->getData(point, c) && c != VISIBLE)
		return false;
		
	PointList neighbors = getNeighbors(point, true);
	for(PointList::const_iterator cell = neighbors.begin(); cell < neighbors.end(); cell++) {
        char c = 0;
		if(map->getData(*cell, c) && c == UNKNOWN) { 
			return true;
        }
    }

	return false;
}
Pose Planner::getCoverageTarget(Pose start)
{
	GridPoint startPoint;
	startPoint.x = start.x;
	startPoint.y = start.y;
	PointList fCells = getFrontierCells(mCoverageMap, startPoint);
	PointList::const_iterator p;
	Pose target;
	for(p = fCells.begin(); p < fCells.end(); p++)
	{
		target.x = p->x;
		target.y = p->y;
                LOG_DEBUG_S << "possible goals: " << target.x << "/" << target.y;
		if(p->distance > 20 && p->distance < 30) break;
	}
	return target;
}
Beispiel #25
0
PointList Board::getFutureBlasts() const {
	PointList bombs = getBombs();
	bombs.splice(bombs.end(), findAll(Element(LL("OTHER_BOMB_BOMBERMAN"))));
	bombs.splice(bombs.end(), findAll(Element(LL("BOMB_BOMBERMAN"))));

	PointList rslt;
	PointList walls = getWalls();
	for (auto bmb : bombs) {
		rslt.push_back(bmb);
		PointList bombSurrs = bmb.getSurrounds(size);
		for (auto surr : bombSurrs) {
			if (std::find(walls.begin(), walls.end(), surr) == walls.end()) {
				rslt.push_back(surr);
			}
		}
	}

	return removeDuplicates(rslt);
}
PointList Planner::getFrontier(GridMap* map, GridMap* plan, GridPoint start)
{
     // Mark the cell as "already added to a frontier" by setting 
     // the value in the plan to 2.
	PointList frontier;
	mFrontierCount++;
	
	// Initialize the queue with the first frontier cell
	Queue queue;
	queue.insert(Entry(0, start));
	plan->setData(start, OBSTACLE);
	
	// Do full search with weightless Dijkstra-Algorithm
	while(!queue.empty())
	{		
		// Get the nearest cell from the queue
		Queue::iterator next = queue.begin();
		int distance = next->first;
		GridPoint point = next->second;
		queue.erase(next);
		
		// Add it to the frontier
		frontier.push_back(point);
		mFrontierCellCount++;
		
		// Add all adjacent frontier cells to the queue
		PointList neighbors = getNeighbors(point, true);
        char c = 0;
		for(PointList::const_iterator cell = neighbors.begin(); cell < neighbors.end(); cell++)
		{
			if(plan->getData(*cell, c) && c != OBSTACLE && isFrontierCell(map, *cell))
			{
				plan->setData(*cell, OBSTACLE);
				queue.insert(Entry(distance+1, *cell));
			}
		}
	}
	
	return frontier;
}
// clip the convex hull 'in' to plane to generate a clipped convex hull 'out'
// return true if points remain after clipping.
unsigned int clip(const Plane& plane,const PointList& in, PointList& out,unsigned int planeMask)
{
    std::vector<float> distance;
    distance.reserve(in.size());
    for(PointList::const_iterator itr=in.begin();
        itr!=in.end();
        ++itr)
    {
        distance.push_back(plane.distance(itr->second));
    }

    out.clear();

    for(unsigned int i=0;i<in.size();++i)
    {
        unsigned int i_1 = (i+1)%in.size(); // do the mod to wrap the index round back to the start.
        
        if (distance[i]>=0.0f)
        {
            out.push_back(in[i]);
            
            
            if (distance[i_1]<0.0f)
            {
                unsigned int mask = (in[i].first & in[i_1].first) | planeMask;
                float r = distance[i_1]/(distance[i_1]-distance[i]);
                out.push_back(Point(mask,in[i].second*r+in[i_1].second*(1.0f-r)));
            }
        
        }
        else if (distance[i_1]>0.0f)
        {
            unsigned int mask = (in[i].first & in[i_1].first) | planeMask;
            float r = distance[i_1]/(distance[i_1]-distance[i]);
            out.push_back(Point(mask,in[i].second*r+in[i_1].second*(1.0f-r)));
        }
    }
    
    return out.size();
}
/*!
  \brief Load geometry (polygon BUD/PAR layers)

  \return number of invalid features
*/
int VFKDataBlockDB::LoadGeometryPolygon()
{
    int  nInvalidNoLines, nInvalidNoRings, nGeometries, nBridges;
    int  rowId, nCount, nCountMax;
    size_t nLines;
    GIntBig iFID;
    bool bIsPar, bNewRing, bFound;

    CPLString    osSQL;
    const char  *vrColumn[2];
    GUIntBig     vrValue[2];
    GUIntBig     id, idOb;

    sqlite3_stmt *hStmt;

    VFKReaderDB    *poReader;
    VFKDataBlockDB *poDataBlockLines1, *poDataBlockLines2;
    VFKFeatureDB   *poFeature;

    VFKFeatureDBList  poLineList;
    /* first is to be considered as exterior */
    PointListArray        poRingList;

    std::vector<OGRLinearRing *> poLinearRingList;
    OGRPolygon     ogrPolygon;
    OGRLinearRing *poOgrRing;

    nInvalidNoLines = nInvalidNoRings = nGeometries = 0;
    poReader  = (VFKReaderDB*) m_poReader;

    if (EQUAL (m_pszName, "PAR")) {
        poDataBlockLines1 = (VFKDataBlockDB *) m_poReader->GetDataBlock("HP");
        poDataBlockLines2 = poDataBlockLines1;
        bIsPar = TRUE;
    }
    else {
        poDataBlockLines1 = (VFKDataBlockDB *) m_poReader->GetDataBlock("OB");
        poDataBlockLines2 = (VFKDataBlockDB *) m_poReader->GetDataBlock("SBP");
        bIsPar = FALSE;
    }
    if (NULL == poDataBlockLines1) {
        CPLError(CE_Warning, CPLE_FileIO,
                 "Data block %s not found. Unable to build geometry for %s.", 
                 bIsPar ? "HP" : "OB", m_pszName);
        return -1;
    }
    if (NULL == poDataBlockLines2) {
        CPLError(CE_Warning, CPLE_FileIO,
                 "Data block %s not found. Unable to build geometry for %s.",
                 "SBP", m_pszName);
        return -1;
    }

    poDataBlockLines1->LoadGeometry();
    poDataBlockLines2->LoadGeometry();

    if (LoadGeometryFromDB()) /* try to load geometry from DB */
	return 0;

    if (bIsPar) {
        vrColumn[0] = "PAR_ID_1";
        vrColumn[1] = "PAR_ID_2";
    }
    else {
        vrColumn[0] = "OB_ID";
        vrColumn[1] = "PORADOVE_CISLO_BODU";
        vrValue[1]  = 1;
    }

    osSQL.Printf("SELECT ID,%s,rowid FROM %s", FID_COLUMN, m_pszName);
    if (poReader->IsSpatial())
	poReader->ExecuteSQL("BEGIN");

    std::vector<VFKDbValue> record;
    record.push_back(VFKDbValue(DT_BIGINT));
    record.push_back(VFKDbValue(DT_BIGINT));
    record.push_back(VFKDbValue(DT_INT));
    poReader->PrepareStatement(osSQL.c_str());
    while(poReader->ExecuteSQL(record) == OGRERR_NONE) {
        nBridges = 0;

        /* read values */
        id        = static_cast<GIntBig> (record[0]);
        iFID      = static_cast<GIntBig> (record[1]);
        rowId     = static_cast<int> (record[2]);

        poFeature = (VFKFeatureDB *) GetFeatureByIndex(rowId - 1);
        CPLAssert(NULL != poFeature && poFeature->GetFID() == iFID);

        if (bIsPar) {
            vrValue[0] = vrValue[1] = id;
            poLineList = poDataBlockLines1->GetFeatures(vrColumn, vrValue, 2);
        }
        else {
            VFKFeatureDB *poLineSbp;
            std::vector<VFKFeatureDB *> poLineListOb;
            sqlite3_stmt *hStmtOb;

            osSQL.Printf("SELECT ID FROM %s WHERE BUD_ID = " CPL_FRMT_GUIB,
                         poDataBlockLines1->GetName(), id);
            if (poReader->IsSpatial()) {
                CPLString osColumn;

                osColumn.Printf(" AND %s IS NULL", GEOM_COLUMN);
                osSQL += osColumn;
            }

            std::vector<VFKDbValue> record1;
            record1.push_back(VFKDbValue(DT_BIGINT));
            poReader->PrepareStatement(osSQL.c_str(), 1);
            while(poReader->ExecuteSQL(record, 1) == OGRERR_NONE) {
                idOb = static_cast<GIntBig> (record[0]);
                vrValue[0] = idOb;
                poLineSbp = poDataBlockLines2->GetFeature(vrColumn, vrValue, 2);
                if (poLineSbp)
                    poLineList.push_back(poLineSbp);
            }
        }
        nLines = poLineList.size();
        if (nLines < 1) {
            CPLDebug("OGR-VFK",
                     "%s: unable to collect rings for polygon fid = %ld (no lines)",
                     m_pszName, iFID);
            nInvalidNoLines++;
            continue;
        }

        /* clear */
        ogrPolygon.empty();
        poRingList.clear();

        /* collect rings from lines */
        bFound = FALSE;
        nCount = 0;
        nCountMax = static_cast<int>(nLines) * 2;
	while (poLineList.size() > 0 && nCount < nCountMax) {
            bNewRing = !bFound ? TRUE : FALSE;
            bFound = FALSE;
            int i = 1;
            for (VFKFeatureDBList::iterator iHp = poLineList.begin(), eHp = poLineList.end();
                 iHp != eHp; ++iHp, ++i) {
                const OGRLineString *pLine = (OGRLineString *) (*iHp)->GetGeometry();
                if (pLine && AppendLineToRing(&poRingList, pLine, bNewRing)) {
                    bFound = TRUE;
                    poLineList.erase(iHp);
                    break;
                }
            }
            nCount++;
        }
        CPLDebug("OGR-VFK", "%s: fid = %ld nlines = %d -> nrings = %d", m_pszName,
                 iFID, (int)nLines, (int)poRingList.size());

        if (poLineList.size() > 0) {
            CPLDebug("OGR-VFK",
                     "%s: unable to collect rings for polygon fid = %ld",
                     m_pszName, iFID);
            nInvalidNoRings++;
            continue;
        }

        /* build rings */
	poLinearRingList.clear();
	int i = 1;
        for (PointListArray::const_iterator iRing = poRingList.begin(), eRing = poRingList.end();
             iRing != eRing; ++iRing) {
	    OGRPoint *poPoint;
            PointList *poList = *iRing;

            poLinearRingList.push_back(new OGRLinearRing());
	    poOgrRing = poLinearRingList.back();
	    CPLAssert(NULL != poOgrRing);

            for (PointList::iterator iPoint = poList->begin(), ePoint = poList->end();
                 iPoint != ePoint; ++iPoint) {
		poPoint = &(*iPoint);
                poOgrRing->addPoint(poPoint);
            }
	    i++;
	}

	/* find exterior ring */
	if (poLinearRingList.size() > 1) {
	    double dArea, dMaxArea;
	    std::vector<OGRLinearRing *>::iterator exteriorRing;

	    exteriorRing = poLinearRingList.begin();
	    dMaxArea = -1.;
	    for (std::vector<OGRLinearRing *>::iterator iRing = poLinearRingList.begin(),
		     eRing = poLinearRingList.end(); iRing != eRing; ++iRing) {
		poOgrRing = *iRing;
		if (!IsRingClosed(poOgrRing))
		    continue; /* skip unclosed rings */

		dArea = poOgrRing->get_Area();
		if (dArea > dMaxArea) {
		    dMaxArea = dArea;
		    exteriorRing = iRing;
		}
	    }
	    if (exteriorRing != poLinearRingList.begin()) {
		std::swap(*poLinearRingList.begin(), *exteriorRing);
	    }
	}

	/* build polygon from rings */
        for (std::vector<OGRLinearRing *>::iterator iRing = poLinearRingList.begin(),
		 eRing = poLinearRingList.end(); iRing != eRing; ++iRing) {
	    poOgrRing = *iRing;

	    /* check if ring is closed */
	    if (IsRingClosed(poOgrRing)) {
		ogrPolygon.addRing(poOgrRing);
            }
	    else {
                if (poOgrRing->getNumPoints() == 2) {
                    CPLDebug("OGR-VFK", "%s: Polygon (fid = %ld) bridge removed",
                             m_pszName, iFID);
                    nBridges++;
                }
                else {
                    CPLDebug("OGR-VFK",
                             "%s: Polygon (fid = %ld) unclosed ring skipped",
                             m_pszName, iFID);
                }
            }
	    delete poOgrRing;
            *iRing = NULL;
        }

        /* set polygon */
        ogrPolygon.setCoordinateDimension(2); /* force 2D */
        if (ogrPolygon.getNumInteriorRings() + nBridges != (int) poLinearRingList.size() - 1 ||
            !poFeature->SetGeometry(&ogrPolygon)) {
            nInvalidNoRings++;
            continue;
        }

        /* store also geometry in DB */
        if (poReader->IsSpatial() &&
	    SaveGeometryToDB(&ogrPolygon, rowId) != OGRERR_FAILURE)
            nGeometries++;
    }

    /* free ring list */
    for (PointListArray::iterator iRing = poRingList.begin(), eRing = poRingList.end();
         iRing != eRing; ++iRing) {
        delete (*iRing);
        *iRing = NULL;
    }

    CPLDebug("OGR-VFK", "%s: nolines = %d norings = %d",
             m_pszName, nInvalidNoLines, nInvalidNoRings);

    /* update number of geometries in VFK_DB_TABLE table */
    UpdateVfkBlocks(nGeometries);

    if (poReader->IsSpatial())
	poReader->ExecuteSQL("COMMIT");

    return nInvalidNoLines + nInvalidNoRings;
}
Beispiel #29
0
/*!
  \brief Load geometry (polygon BUD/PAR layers)

  \return number of invalid features
*/
int VFKDataBlock::LoadGeometryPolygon()
{
    long nInvalid;
    bool bIsPar, bNewRing, bFound;
        
    GUIntBig id, idOb;
    int  nCount, nCountMax;
    int idxId, idxPar1, idxPar2, idxBud, idxOb, idxIdOb;
    
    VFKFeature   *poFeature;
    VFKDataBlock *poDataBlockLines1, *poDataBlockLines2;
    
    VFKFeatureList   poLineList;
    PointListArray   poRingList; /* first is to be considered as exterior */
    
    OGRLinearRing ogrRing;
    OGRPolygon    ogrPolygon;
    
    idxPar1 = idxPar2 = idxBud = idxOb = idxIdOb = 0;
    nInvalid = 0;
    if (EQUAL (m_pszName, "PAR")) {
        poDataBlockLines1 = (VFKDataBlock *) m_poReader->GetDataBlock("HP");
        poDataBlockLines2 = poDataBlockLines1;
        bIsPar = TRUE;
    }
    else {
        poDataBlockLines1 = (VFKDataBlock *) m_poReader->GetDataBlock("OB");
        poDataBlockLines2 = (VFKDataBlock *) m_poReader->GetDataBlock("SBP");
        bIsPar = FALSE;
    }
    if (NULL == poDataBlockLines1 || NULL == poDataBlockLines2) {
        CPLError(CE_Failure, CPLE_NotSupported, 
                 "Data block %s not found.\n", m_pszName);
        return nInvalid;
    }
    
    poDataBlockLines1->LoadGeometry();
    poDataBlockLines2->LoadGeometry();
    idxId = GetPropertyIndex("ID");
    if (idxId < 0) {
        CPLError(CE_Failure, CPLE_NotSupported, 
                 "Corrupted data (%s).\n", m_pszName);
        return nInvalid;
    }
    
    if (bIsPar) {
        idxPar1 = poDataBlockLines1->GetPropertyIndex("PAR_ID_1");
        idxPar2 = poDataBlockLines1->GetPropertyIndex("PAR_ID_2");
        if (idxPar1 < 0 || idxPar2 < 0) {
            CPLError(CE_Failure, CPLE_NotSupported, 
                     "Corrupted data (%s).\n", m_pszName);
            return nInvalid;
        }
    }
    else { /* BUD */
        idxIdOb  = poDataBlockLines1->GetPropertyIndex("ID");
        idxBud = poDataBlockLines1->GetPropertyIndex("BUD_ID");
        idxOb  = poDataBlockLines2->GetPropertyIndex("OB_ID");
        if (idxIdOb < 0 || idxBud < 0 || idxOb < 0) {
            CPLError(CE_Failure, CPLE_NotSupported, 
                     "Corrupted data (%s).\n", m_pszName);
            return nInvalid;
        }
    }
    
    for (int i = 0; i < ((IVFKDataBlock *) this)->GetFeatureCount(); i++) {
        poFeature = (VFKFeature *) GetFeatureByIndex(i);
        id = strtoul(poFeature->GetProperty(idxId)->GetValueS(), NULL, 0);
        if (bIsPar) {
            poLineList = poDataBlockLines1->GetFeatures(idxPar1, idxPar2, id);
        }
        else {
            VFKFeature *poLineOb, *poLineSbp;
            std::vector<VFKFeature *> poLineListOb;
            poLineListOb = poDataBlockLines1->GetFeatures(idxBud, id);
            for (std::vector<VFKFeature *>::const_iterator iOb = poLineListOb.begin(), eOb = poLineListOb.end();
                 iOb != eOb; ++iOb) {
                poLineOb = (*iOb);
                idOb = strtoul(poLineOb->GetProperty(idxIdOb)->GetValueS(), NULL, 0);
                poLineSbp = poDataBlockLines2->GetFeature(idxOb, idOb);
                if (poLineSbp)
                    poLineList.push_back(poLineSbp);
            }
        }
        if (poLineList.size() < 1)
            continue;
        
        /* clear */
        ogrPolygon.empty();
        poRingList.clear();
        
        /* collect rings (points) */
        bFound = FALSE;
        nCount = 0;
        nCountMax = poLineList.size() * 2;
        while (poLineList.size() > 0 && nCount < nCountMax) {
            bNewRing = !bFound ? TRUE : FALSE;
            bFound = FALSE;
            for (VFKFeatureList::iterator iHp = poLineList.begin(), eHp = poLineList.end();
                 iHp != eHp; ++iHp) {
                const OGRLineString *pLine = (OGRLineString *) (*iHp)->GetGeometry();
                if (pLine && AppendLineToRing(&poRingList, pLine, bNewRing)) {
                    bFound = TRUE;
                    poLineList.erase(iHp);
                    break;
                }
            }
            nCount++;
        }
        /* create rings */
        for (PointListArray::const_iterator iRing = poRingList.begin(), eRing = poRingList.end();
             iRing != eRing; ++iRing) {
            PointList *poList = *iRing;
            ogrRing.empty();
            for (PointList::iterator iPoint = poList->begin(), ePoint = poList->end();
                 iPoint != ePoint; ++iPoint) {
                ogrRing.addPoint(&(*iPoint));
            }
            ogrPolygon.addRing(&ogrRing);
        }
        /* set polygon */
        ogrPolygon.setCoordinateDimension(2); /* force 2D */
        if (!poFeature->SetGeometry(&ogrPolygon))
            nInvalid++;
    }
    
    /* free ring list */
    for (PointListArray::iterator iRing = poRingList.begin(),
             eRing = poRingList.end(); iRing != eRing; ++iRing) {
        delete (*iRing);
        *iRing = NULL;
    }
    poDataBlockLines1->ResetReading();
    poDataBlockLines2->ResetReading();

    return nInvalid;
}
// adapted from http://www.cgal.org/Manual/beta/examples/Surface_reconstruction_points_3/poisson_reconstruction_example.cpp
Mesh poissonSurface(const Mat ipoints, const Mat normals)
{
    // Poisson options
    FT sm_angle = 20.0; // Min triangle angle in degrees.
    FT sm_radius = 300; // Max triangle size w.r.t. point set average spacing.
    FT sm_distance = 0.375; // Surface Approximation error w.r.t. point set average spacing.

    PointList points;
    points.reserve(ipoints.rows);
    float min = 0, max = 0;
    for (int i=0; i<ipoints.rows; i++) {
        float const *p = ipoints.ptr<float const>(i), *n = normals.ptr<float const>(i);
        points.push_back(Point_with_normal(Point(p[0]/p[3], p[1]/p[3], p[2]/p[3]), Vector(n[0], n[1], n[2])));
        if (p[0]/p[3] > max) max = p[0]/p[3];
        if (p[0]/p[3] < min) min = p[0]/p[3];
    }

    // Creates implicit function from the read points using the default solver.

    // Note: this method requires an iterator over points
    // + property maps to access each point's position and normal.
    // The position property map can be omitted here as we use iterators over Point_3 elements.
    Poisson_reconstruction_function function(points.begin(), points.end(), CGAL::make_normal_of_point_with_normal_pmap(points.begin()) );

    // Computes the Poisson indicator function f() at each vertex of the triangulation.
    bool success = function.compute_implicit_function();
    assert(success);
#ifdef TEST_BUILD
    printf("implicit function ready. Meshing...\n");
#endif
    // Computes average spacing
    FT average_spacing = CGAL::compute_average_spacing(points.begin(), points.end(), 6 /* knn = 1 ring */);

    // Gets one point inside the implicit surface
    // and computes implicit function bounding sphere radius.
    Point inner_point = function.get_inner_point();
    Sphere bsphere = function.bounding_sphere();
    FT radius = std::sqrt(bsphere.squared_radius());

    // Defines the implicit surface: requires defining a
    // conservative bounding sphere centered at inner point.
    FT sm_sphere_radius = 5.0 * radius;
    FT sm_dichotomy_error = sm_distance*average_spacing/1000.0; // Dichotomy error must be << sm_distance
    Surface_3 surface(function, Sphere(inner_point,sm_sphere_radius*sm_sphere_radius), sm_dichotomy_error/sm_sphere_radius);

    // Defines surface mesh generation criteria
    // parameters: min triangle angle (degrees), max triangle size, approximation error
    CGAL::Surface_mesh_default_criteria_3<STr> criteria(sm_angle, sm_radius*average_spacing, sm_distance*average_spacing);

    // Generates surface mesh with manifold option
    STr tr; // 3D Delaunay triangulation for surface mesh generation
    C2t3 c2t3(tr); // 2D complex in 3D Delaunay triangulation
    // parameters: reconstructed mesh, implicit surface, meshing criteria, 'do not require manifold mesh'
    CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Non_manifold_tag());

    assert(tr.number_of_vertices() > 0);

    // Search structure: index of the vertex at an exactly given position
    std::map<Point, int> vertexIndices;

    // Extract all vertices of the resulting mesh
    Mat vertices(tr.number_of_vertices(), 4, CV_32FC1), faces(c2t3.number_of_facets(), 3, CV_32SC1);
#ifdef TEST_BUILD
    printf("%i vertices, %i facets. Converting...\n", vertices.rows, faces.rows);
#endif
    {   int i=0;
        for (C2t3::Vertex_iterator it=c2t3.vertices_begin(); it!=c2t3.vertices_end(); it++, i++) {
            float *vertex = vertices.ptr<float>(i);
            Point p = it->point();
            vertex[0] = p.x();
            vertex[1] = p.y();
            vertex[2] = p.z();
            vertex[3] = 1;
            vertexIndices[p] = i;
        }
        vertices.resize(i);
    }

    // Extract all faces of the resulting mesh and calculate the index of each of their vertices
    {   int i=0;
        for (C2t3::Facet_iterator it=c2t3.facets_begin(); it!=c2t3.facets_end(); it++, i++) {
            Cell cell = *it->first;
            int vertex_excluded = it->second;
            int32_t* outfacet = faces.ptr<int32_t>(i);
            // a little magic so that face normals are oriented outside
            char sign = (function(cell.vertex(vertex_excluded)->point()) > 0) ? 1 : 2; // 2 = -1 (mod 3)
            for (char j = vertex_excluded + 1; j < vertex_excluded + 4; j++) {
                outfacet[(sign*j)%3] = vertexIndices[cell.vertex(j%4)->point()];
            }
        }
    }

    return Mesh(vertices, faces);
}