int SHAPE_POLY_SET::NewOutline()
{
    SHAPE_LINE_CHAIN empty_path;
    POLYGON poly;
    poly.push_back( empty_path );
    m_polys.push_back( poly );
    return m_polys.size() - 1;
}
bool SHAPE_POLY_SET::Parse( std::stringstream& aStream )
{
    std::string tmp;

    aStream >> tmp;

    if( tmp != "polyset" )
        return false;

    aStream >> tmp;

    int n_polys = atoi( tmp.c_str() );

    if( n_polys < 0 )
        return false;

    for( int i = 0; i < n_polys; i++ )
    {
        POLYGON paths;

        aStream >> tmp;

        if( tmp != "poly" )
            return false;

        aStream >> tmp;
        int n_outlines = atoi( tmp.c_str() );

        if( n_outlines < 0 )
            return false;

        for( int j = 0; j < n_outlines; j++ )
        {
            SHAPE_LINE_CHAIN outline;

            outline.SetClosed( true );

            aStream >> tmp;
            int n_vertices = atoi( tmp.c_str() );
            for( int v = 0; v < n_vertices; v++ )
            {
                VECTOR2I p;

                aStream >> tmp; p.x = atoi( tmp.c_str() );
                aStream >> tmp; p.y = atoi( tmp.c_str() );
                outline.Append( p );
            }

            paths.push_back( outline );
        }

        m_polys.push_back( paths );
    }
    return true;
}
int SHAPE_POLY_SET::AddOutline( const SHAPE_LINE_CHAIN& aOutline )
{
    assert( aOutline.IsClosed() );

    POLYGON poly;

    poly.push_back( aOutline );

    m_polys.push_back( poly );

    return m_polys.size() - 1;
}
void SHAPE_POLY_SET::fractureSingle( POLYGON& paths )
{
    FractureEdgeSet edges;
    FractureEdgeSet border_edges;
    FractureEdge* root = NULL;

    bool first = true;

    if( paths.size() == 1 )
        return;

    int num_unconnected = 0;

    BOOST_FOREACH( SHAPE_LINE_CHAIN& path, paths )
    {
        int index = 0;

        FractureEdge *prev = NULL, *first_edge = NULL;

        int x_min = std::numeric_limits<int>::max();

        for( int i = 0; i < path.PointCount(); i++ )
        {
            const VECTOR2I& p = path.CPoint( i );

            if( p.x < x_min )
                x_min = p.x;
        }

        for( int i = 0; i < path.PointCount(); i++ )
        {
            FractureEdge* fe = new FractureEdge( first, &path, index++ );

            if( !root )
                root = fe;

            if( !first_edge )
                first_edge = fe;

            if( prev )
                prev->m_next = fe;

            if( i == path.PointCount() - 1 )
                fe->m_next = first_edge;

            prev = fe;
            edges.push_back( fe );

            if( !first )
            {
                if( fe->m_p1.x == x_min )
                    border_edges.push_back( fe );
            }

            if( !fe->m_connected )
                num_unconnected++;
        }
        first = false; // first path is always the outline
    }
Пример #5
0
void fitSVG(const POLYGON& _polygon, gex::io::SVG& _svg)
{
  using namespace gex;
  auto& _bounds = _polygon.bounds();
  auto&& _center = _bounds.center();
  auto&& _max = (_bounds.size()(X) + _bounds.size()(Y)) / 2.0;
  Vec2 _m(_max,_max);
  _svg.buffer().fit(Bounds2(_center - _m,_center + _m));
}
void SHAPE_POLY_SET::importTree( PolyTree* tree)
{
    m_polys.clear();

    for( PolyNode* n = tree->GetFirst(); n; n = n->GetNext() )
    {
        if( !n->IsHole() )
        {
            POLYGON paths;
            paths.push_back( convertFromClipper( n->Contour ) );

            for( unsigned int i = 0; i < n->Childs.size(); i++ )
                paths.push_back( convertFromClipper( n->Childs[i]->Contour ) );

            m_polys.push_back(paths);
        }
    }
}
Пример #7
0
// extended methods
int SIMPLEPOLY::SetValues( const POLYGON& aPolygon )
{
    if( x )
        delete [] x;

    if( y )
        delete [] y;

    if( z )
        delete [] z;

    x = y = z = NULL;
    nv = 0;
    valid = false;

    int np;
    double* px, * py, * pz;
    px  = py = pz = NULL;
    np  = aPolygon.GetVertices( &px, &py, &pz );

    if( np < 3 )
        return 0;         // polygons must have 3 or more vertices

    if( (!px) || (!py) || (!pz) )
    {
        ERRBLURB;
        cerr << "invalid pointer to coordinate\n";
        return -1;
    }

    x = new (nothrow) double[np];

    if( x == NULL )
    {
        ERRBLURB;
        cerr << "could not allocate memory for vertices\n";
        return -1;
    }

    y = new (nothrow) double[np];

    if( y == NULL )
    {
        ERRBLURB;
        cerr << "could not allocate memory for vertices\n";
        delete [] x;
        return -1;
    }

    z = new (nothrow) double[np];

    if( z == NULL )
    {
        ERRBLURB;
        cerr << "could not allocate memory for vertices\n";
        delete [] x;
        delete [] y;
        return -1;
    }

    int i;

    for( i = 0; i < np; ++i )
    {
        x[i] = px[i];
        y[i] = py[i];
        z[i] = pz[i];
    }

    valid = true;
    nv = np;
    return 0;
}
Пример #8
0
int POLYGON::Stitch( bool isCCW, POLYGON& aPolygon, TRANSFORM& aTransform, VRMLMAT& aMaterial,
                     bool reuseMaterial, std::ofstream& aVRMLFile, int aTabDepth )
{
    int i, j, k;

    if( !valid )
    {
        ERRBLURB;
        cerr << "invoked without prior invocation of Calc()\n";
        return -1;
    }

    if( nv < 3 )
    {
        ERRBLURB;
        cerr << "invalid number of vertices (" << nv << "); range is 3 .. 360\n";
        return -1;
    }

    double* r2x = NULL;
    double* r2y = NULL;
    double* r2z = NULL;
    int rv = aPolygon.GetVertices( &r2x, &r2y, &r2z );

    if( rv != nv )
    {
        ERRBLURB;
        cerr << "points in second ring (" << rv << ") do not match points in this ring (" << nv <<
        ")\n";
        return -1;
    }

    if( aTabDepth < 0 )
        aTabDepth = 0;

    if( aTabDepth > 4 )
        aTabDepth = 4;

    double* lx;
    double* ly;
    double* lz;

    // allocate memory
    lx = new double[nv * 2];

    if( lx == NULL )
    {
        ERRBLURB;
        cerr << "could not allocate points for intermediate calculations\n";
        return -1;
    }

    ly = new double[nv * 2];

    if( ly == NULL )
    {
        ERRBLURB;
        cerr << "could not allocate points for intermediate calculations\n";
        delete [] lx;
        return -1;
    }

    lz = new double[nv * 2];

    if( lz == NULL )
    {
        ERRBLURB;
        cerr << "could not allocate points for intermediate calculations\n";
        delete [] lx;
        delete [] ly;
        return -1;
    }

    for( i = 0; i < nv; ++i )
    {
        lx[i] = x[i];
        ly[i] = y[i];
        lz[i] = z[i];
        lx[i + nv]  = r2x[i];
        ly[i + nv]  = r2y[i];
        lz[i + nv]  = r2z[i];
    }

    // perform transforms
    aTransform.Transform( lx, ly, lz, nv * 2 );

    // set up VRML Shape
    SetupShape( aMaterial, reuseMaterial, aVRMLFile, aTabDepth );
    // enumerate vertices
    WriteCoord( lx, ly, lz, nv * 2, aVRMLFile, aTabDepth + 1 );
    // enumerate facets
    SetupCoordIndex( aVRMLFile, aTabDepth + 1 );
    string fmt( (aTabDepth + 1) * 4, ' ' );
    aVRMLFile << fmt << "   ";

    if( isCCW )
        k = 1;
    else
        k = -1;

    for( i = 0; i < nv - 1; ++i )
    {
        j = i + k;

        if( j >= nv )
            j -= nv;

        if( j < 0 )
            j += nv;

        aVRMLFile << " " << i << "," << j << "," << j + nv << "," << i + nv << ",-1,";

        if( !( (i + 1) % 4 ) )
            aVRMLFile << "\n" << fmt << "   ";
    }

    j = i + k;

    if( j >= nv )
        j -= nv;

    if( j < 0 )
        j += nv;

    aVRMLFile << " " << i << "," << j << "," << j + nv << "," << i + nv << ",-1\n";

    CloseCoordIndex( aVRMLFile, aTabDepth + 1 );

    delete [] lx;
    delete [] ly;
    delete [] lz;

    return CloseShape( aVRMLFile, aTabDepth );
}
Пример #9
0
  return gb;
 }

}

void hp_inter(const list<LINE>& Lin, list<rat_polygon>& Lout)
{
 if (Lin.size() < 1) return;
 int HP_NUMB=Lin.size(),i;
 array<LINE> L(HP_NUMB);
 LINE lakt;
 i=0;
 forall(lakt,Lin) { L[i]=lakt; i++; }

 POLYGON GP = halfplane_intersection(L,0,HP_NUMB-1);
 
 Lout = GP.polygons();
}

POINT get_dual(const LINE& l)
{
 POINT p1 = l.point1();
 POINT p2 = l.point2();
 POINT swp;
 
 if (p1.xcoord() > p2.xcoord()) { swp=p1; p1=p2; p2=swp; }

 NUMBER2 a,b,x1,x2,y1,y2;
 x1=p1.xcoord(); y1=p1.ycoord();
 x2=p2.xcoord(); y2=p2.ycoord();
Пример #10
0
bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttribute<typename PFP::VEC3>& position, CellMarker<EDGE>& polygons, CellMarker<FACE>& polygonsFaces)
{
	typedef typename PFP::VEC3 VEC3;
	typedef std::vector<VEC3 > POLYGON;

	xmlDocPtr doc = xmlReadFile(filename.c_str(), NULL, 0);
	xmlNodePtr map_node = xmlDocGetRootElement(doc);

	if (!checkXmlNode(map_node,"svg"))
	{
		CGoGNerr << "Wrong xml format: Root node != svg"<< CGoGNendl;
		return false;
	}

	std::vector<POLYGON> allPoly;
	std::vector<POLYGON> allBrokenLines;
	std::vector<float> allBrokenLinesWidth;
	bool closedPoly;

	for (xmlNode* cur_node = map_node->children; cur_node; cur_node = cur_node->next)
	{
		// for each layer
		if (checkXmlNode(cur_node, "g"))
		{
//			CGoGNout << "----load layer----"<< CGoGNendl;

			for (xmlNode* cur_path = cur_node->children ; cur_path; cur_path = cur_path->next)
			{
				if (checkXmlNode(cur_path, "path"))
				{
					POLYGON curPoly;
//					CGoGNout << "--load a path--"<< CGoGNendl;
					xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "d");
					std::string allcoords((reinterpret_cast<const char*>(prop)));
					getPolygonFromSVG(allcoords,curPoly,closedPoly);

					//check orientation : set in CCW
					if(curPoly.size()>2)
					{
						VEC3 v1(curPoly[1]-curPoly[0]);
						VEC3 v2(curPoly[2]-curPoly[1]);
						if((v1^v2)[2]>0)
						{
							std::reverse(curPoly.begin(), curPoly.end());
						}
					}

					if(closedPoly)
						allPoly.push_back(curPoly);
					else
					{
						allBrokenLines.push_back(curPoly);
						xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "style");
						std::string allstyle((reinterpret_cast<const char*>(prop)));
						std::stringstream is(allstyle);
						std::string style;
						while ( std::getline( is, style, ';' ) )
						{
							if(style.find("stroke-width:")!=std::string::npos)
							{
								std::stringstream isSize(style);
								std::getline( isSize, style, ':' );
								float sizeOfLine;
								isSize >> sizeOfLine;
								allBrokenLinesWidth.push_back(sizeOfLine);
							}
						}
					}
				}
			}
		}
void SHAPE_POLY_SET::fractureSingle( POLYGON& paths )
{
    FractureEdgeSet edges;
    FractureEdgeSet border_edges;
    FractureEdge* root = NULL;

    bool first = true;

    if( paths.size() == 1 )
        return;

    int num_unconnected = 0;

    for( SHAPE_LINE_CHAIN& path : paths )
    {
        int index = 0;

        FractureEdge *prev = NULL, *first_edge = NULL;

        int x_min = std::numeric_limits<int>::max();

        for( int i = 0; i < path.PointCount(); i++ )
        {
            const VECTOR2I& p = path.CPoint( i );

            if( p.x < x_min )
                x_min = p.x;
        }

        for( int i = 0; i < path.PointCount(); i++ )
        {
            FractureEdge* fe = new FractureEdge( first, &path, index++ );

            if( !root )
                root = fe;

            if( !first_edge )
                first_edge = fe;

            if( prev )
                prev->m_next = fe;

            if( i == path.PointCount() - 1 )
                fe->m_next = first_edge;

            prev = fe;
            edges.push_back( fe );

            if( !first )
            {
                if( fe->m_p1.x == x_min )
                    border_edges.push_back( fe );
            }

            if( !fe->m_connected )
                num_unconnected++;
        }
        first = false; // first path is always the outline
    }

    // keep connecting holes to the main outline, until there's no holes left...
    while( num_unconnected > 0 )
    {
        int x_min = std::numeric_limits<int>::max();

        FractureEdge* smallestX = NULL;

        // find the left-most hole edge and merge with the outline
        for( FractureEdgeSet::iterator i = border_edges.begin(); i != border_edges.end(); ++i )
        {
            int xt = (*i)->m_p1.x;

            if( ( xt < x_min ) && ! (*i)->m_connected )
            {
                x_min = xt;
                smallestX = *i;
            }
        }

        num_unconnected -= processEdge( edges, smallestX );
    }

    paths.clear();
    SHAPE_LINE_CHAIN newPath;

    newPath.SetClosed( true );

    FractureEdge* e;

    for( e = root; e->m_next != root; e = e->m_next )
        newPath.Append( e->m_p1 );

    newPath.Append( e->m_p1 );

    for( FractureEdgeSet::iterator i = edges.begin(); i != edges.end(); ++i )
        delete *i;

    paths.push_back( newPath );
}