Beispiel #1
0
void
Surface_mesh::
flip(Edge e)
{
    // CAUTION : Flipping a halfedge may result in
    // a non-manifold mesh, hence check for yourself
    // whether this operation is allowed or not!

    //let's make it sure it is actually checked
    assert(is_flip_ok(e));

    Halfedge a0 = halfedge(e, 0);
    Halfedge b0 = halfedge(e, 1);

    Halfedge a1 = next_halfedge(a0);
    Halfedge a2 = next_halfedge(a1);

    Halfedge b1 = next_halfedge(b0);
    Halfedge b2 = next_halfedge(b1);

    Vertex   va0 = to_vertex(a0);
    Vertex   va1 = to_vertex(a1);

    Vertex   vb0 = to_vertex(b0);
    Vertex   vb1 = to_vertex(b1);

    Face     fa  = face(a0);
    Face     fb  = face(b0);

    set_vertex(a0, va1);
    set_vertex(b0, vb1);

    set_next_halfedge(a0, a2);
    set_next_halfedge(a2, b1);
    set_next_halfedge(b1, a0);

    set_next_halfedge(b0, b2);
    set_next_halfedge(b2, a1);
    set_next_halfedge(a1, b0);

    set_face(a1, fb);
    set_face(b1, fa);

    set_halfedge(fa, a0);
    set_halfedge(fb, b0);

    if (halfedge(va0) == b0)
        set_halfedge(va0, a1);
    if (halfedge(vb0) == a0)
        set_halfedge(vb0, b1);
}
Beispiel #2
0
void
Surface_mesh::
split(Face f, Vertex v)
{
    /*
     Split an arbitrary face into triangles by connecting each vertex of fh to vh.
     - fh will remain valid (it will become one of the triangles)
     - the halfedge handles of the new triangles will point to the old halfeges
     */

    Halfedge hend = halfedge(f);
    Halfedge h    = next_halfedge(hend);

    Halfedge hold = new_edge(to_vertex(hend), v);

    set_next_halfedge(hend, hold);
    set_face(hold, f);

    hold = opposite_halfedge(hold);

    while (h != hend)
    {
        Halfedge hnext = next_halfedge(h);

        Face fnew = new_face();
        set_halfedge(fnew, h);

        Halfedge hnew = new_edge(to_vertex(h), v);

        set_next_halfedge(hnew, hold);
        set_next_halfedge(hold, h);
        set_next_halfedge(h,    hnew);

        set_face(hnew, fnew);
        set_face(hold, fnew);
        set_face(h,    fnew);

        hold = opposite_halfedge(hnew);

        h = hnext;
    }

    set_next_halfedge(hold, hend);
    set_next_halfedge(next_halfedge(hend), hold);

    set_face(hold, f);

    set_halfedge(v, hold);
}
Beispiel #3
0
void
Surface_mesh::
triangulate(Face f)
{
    /*
     Split an arbitrary face into triangles by connecting
     each vertex of fh after its second to vh.

     - fh will remain valid (it will become one of the
     triangles)
     - the halfedge handles of the new triangles will
     point to the old halfedges
     */

    Halfedge base_h  = halfedge(f);
    Vertex   start_v = from_vertex(base_h);
    Halfedge next_h  = next_halfedge(base_h);

    while (to_vertex(next_halfedge(next_h)) != start_v)
    {
        Halfedge next_next_h(next_halfedge(next_h));

        Face new_f = new_face();
        set_halfedge(new_f, base_h);

        Halfedge new_h = new_edge(to_vertex(next_h), start_v);

        set_next_halfedge(base_h, next_h);
        set_next_halfedge(next_h, new_h);
        set_next_halfedge(new_h,  base_h);

        set_face(base_h, new_f);
        set_face(next_h, new_f);
        set_face(new_h,  new_f);

        base_h = opposite_halfedge(new_h);
        next_h = next_next_h;
    }
    set_halfedge(f, base_h);  //the last face takes the handle _fh

    set_next_halfedge(base_h, next_h);
    set_next_halfedge(next_halfedge(next_h), base_h);

    set_face(base_h, f);
}
Beispiel #4
0
	CharLook::CharLook(const LookEntry& entry)
	{
		reset();

		set_body(entry.skin);
		set_hair(entry.hairid);
		set_face(entry.faceid);

		for (auto& equip : entry.equips)
		{
			add_equip(equip.second);
		}
	}
Beispiel #5
0
void
Surface_mesh::
remove_loop(Halfedge h)
{
    Halfedge  h0 = h;
    Halfedge  h1 = next_halfedge(h0);

    Halfedge  o0 = opposite_halfedge(h0);
    Halfedge  o1 = opposite_halfedge(h1);

    Vertex    v0 = to_vertex(h0);
    Vertex    v1 = to_vertex(h1);

    Face      fh = face(h0);
    Face      fo = face(o0);



    // is it a loop ?
    assert ((next_halfedge(h1) == h0) && (h1 != o0));


    // halfedge -> halfedge
    set_next_halfedge(h1, next_halfedge(o0));
    set_next_halfedge(prev_halfedge(o0), h1);


    // halfedge -> face
    set_face(h1, fo);


    // vertex -> halfedge
    set_halfedge(v0, h1);  adjust_outgoing_halfedge(v0);
    set_halfedge(v1, o1);  adjust_outgoing_halfedge(v1);


    // face -> halfedge
    if (fo.is_valid() && halfedge(fo) == o0)
        set_halfedge(fo, h1);


    // delete stuff
    if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false);
    if (!fdeleted_) fdeleted_ = face_property<bool>("f:deleted", false);
    if (fh.is_valid()) { fdeleted_[fh] = true; ++deleted_faces_; }
    edeleted_[edge(h0)] = true; ++deleted_edges_;
    garbage_ = true;
}
Beispiel #6
0
void Cubelet::init() {
    // define geometry
    // Red
    //printf("Initiating cubelet with side %d=%d\n", TOP, GREEN);
    face[RED]->setFace(TOP, RED);
    // Green
    face[GREEN]->setFace(LEFT, GREEN);
    // white
    face[WHITE]->setFace(FRONT, WHITE);
    // Blue
    face[BLUE]->setFace(RIGHT, BLUE);
    // yellow
    face[YELLOW]->setFace(REAR, YELLOW);
    // orange
    face[ORANGE]->setFace(BASE, ORANGE);
    
    // set face colours to grey
    for(int i = 0; i < 6; i++) {
        set_face(i, -1);
    }
}
Beispiel #7
0
Cylinder :: Cylinder(float r, float h, int vs, int rs)
{
	// set radius
	radius = r;
	// set height
	height = h/2.0;
	
	// set stack interval
	float stack = h / vs;
	// set slice interval
	float slice = (2 * M_PI) / rs;
	
	// define the number of vertices
	verts_size = (vs + 1) * (rs) + 2;
	verts = new GLfloat*[verts_size];
	
	// define the number of faces
	faces_size = (vs + 1) * rs * 2;
	faces = new int*[faces_size];
	
	// define arrays for normals
	v_norms = new GLfloat*[verts_size];
	f_norms = new GLfloat*[faces_size];
	
	// define to keep track of faces 
	// for vertex normal calculation
	int vert_faces[verts_size];
	
	// VERTICES
	/////////////////////////////////////////////
	
	GLfloat* v;
	
	// current position of the stack on the y-axis
	float curr_stack;
	// current angle of rotation for slice
	float curr_slice;
	// current positions in the array
	int pos, pos2, pos3;
	
	// loop to set "body" vertices
	for( int i = 0; i < vs + 1; i ++ )
	{
		// calculate stack angle
		curr_stack = -i * stack;
		
		for( int j = 0; j < rs; j++ )
		{
			// calculate slice angle
			curr_slice = j * slice;
			
			// calculate position in the array
			pos = i * rs + j;
			
			// allocate a new vertex
			v = new GLfloat[4];
			// set vertex at north pole
			v[0] = radius;
			v[1] = height;
			v[2] = 0;
			v[3] = 1;
			
			// rotate by stack angle
			v_translate(v, 0.0, curr_stack, 0.0);
			// rotate by slice angle
			v_rotate_y(v, curr_slice);
			
			// store in verts array
			verts[pos] = v;
			// initialize vertex normal
			v_norms[pos] = new GLfloat[4];
			init_vector(v_norms[pos]);
			// initalize vertex face count
			vert_faces[pos] = 0;
		}
	}
	
	pos = verts_size - 2;
	// allocate a new vertex
	v = new GLfloat[4];
	// set vertex at north pole
	v[0] = 0;
	v[1] = height;
	v[2] = 0;
	v[3] = 1;
	// store in verts array
	verts[pos] = v;
	// initialize vertex normal
	v_norms[pos] = new GLfloat[4];
	init_vector(v_norms[pos]);
	// initalize vertex face count
	vert_faces[pos] = 0;
	
	pos = verts_size - 1;
	// allocate a new vertex
	v = new GLfloat[4];
	// set vertex at south pole
	v[0] = 0;
	v[1] = -height;
	v[2] = 0;
	v[3] = 1;
	// store in verts array
	verts[pos] = v;
	// initialize vertex normal
	v_norms[pos] = new GLfloat[4];
	init_vector(v_norms[pos]);
	// initalize vertex face count
	vert_faces[pos] = 0;
	
	
	// FACES + NORMALS
	/////////////////////////////////////////////
	
	// position of face in array
	int f_pos;
	
	// first loop sets the body
	for( int i = 0; i < vs; i++ )
	{
		for( int j = 0; j < 2*(rs-1); j+= 2 )
		{
			// calculate position in the array
			pos = i * rs + j/2;
			pos2 = (i + 1) * rs +j/2;
			pos3 = pos2 + 1;
			f_pos = i * 2 * rs + j;
			
			set_face(f_pos, pos, pos2, pos3, vert_faces);
			
			f_pos++;
			pos2++;
			pos3 = pos + 1;
			
			set_face(f_pos, pos, pos2, pos3, vert_faces);
			
		}
		
		// calculate position in the array
		pos = (i * rs)+ rs - 1;
		pos2 = (i + 1) * rs + rs - 1;
		pos3 = (i + 1) * rs;
		f_pos++;
		
		set_face(f_pos, pos, pos2, pos3, vert_faces);
		
		f_pos++;
		pos2 = (i+1) * rs;
		pos3 = i * rs;
		
		set_face(f_pos, pos, pos2, pos3, vert_faces);
	}
	
	// second loop sets the top endcap
	////////////////////////////////////////
	for( int i = 0; i < rs - 1; i++ )
	{
		// set positions in arrays
		pos = verts_size-2;
		pos2 = i;
		pos3 = i + 1;
		f_pos++;
		
		set_face(f_pos, pos, pos2, pos3, vert_faces);
	}
	
	// set positions in arrays
	pos = verts_size-2;
	pos2 = pos3;
	pos3 = 0;
	f_pos++;
	
	set_face(f_pos, pos, pos2, pos3, vert_faces);
	
	// third loop sets the bottom endcap
	////////////////////////////////////////
	for( int i = 0; i < rs - 1; i++ )
	{
		// set positions in arrays
		pos = verts_size-1;
		pos3 = (vs) * rs + i;
		pos2 = pos3 + 1;
		f_pos++;
		
		set_face(f_pos, pos, pos2, pos3, vert_faces);
	}
	
	// set positions in arrays
	pos = verts_size-1;
	pos2 = pos3;
	pos3 = (vs) * rs;
	f_pos++;
	
	set_face(f_pos, pos, pos2, pos3, vert_faces);
	
	// VERTEX NORMALS
	/////////////////////////////////////////////
	
	for( int i = 0; i < verts_size; i++ )
	{
		normalize(v_norms[i]);
	}
	
	v_norms[verts_size-2][0] = 0.0;
	v_norms[verts_size-2][1] = 1.0;
	v_norms[verts_size-2][2] = 0.0;
	v_norms[verts_size-2][3] = 1.0;
	
	v_norms[verts_size-1][0] = 0.0;
	v_norms[verts_size-1][1] = -1.0;
	v_norms[verts_size-1][2] = 0.0;
	v_norms[verts_size-1][3] = 1.0;
}
Beispiel #8
0
void Cube::set_front(int *face) {
    int positions[8] = { 0, 1, 5, 4,    // corners
                         0, 5, 8, 4 };  // edges
    set_face(face, positions);
}
Beispiel #9
0
void
Surface_mesh::
split(Edge e, Vertex v)
{
    Halfedge h0 = halfedge(e, 0);
    Halfedge o0 = halfedge(e, 1);

    Vertex   v2 = to_vertex(o0);

    Halfedge e1 = new_edge(v, v2);
    Halfedge t1 = opposite_halfedge(e1);

    Face     f0 = face(h0);
    Face     f3 = face(o0);

    set_halfedge(v, h0);
    set_vertex(o0, v);

    if (!is_boundary(h0))
    {
        Halfedge h1 = next_halfedge(h0);
        Halfedge h2 = next_halfedge(h1);

        Vertex   v1 = to_vertex(h1);

        Halfedge e0 = new_edge(v, v1);
        Halfedge t0 = opposite_halfedge(e0);

        Face f1 = new_face();
        set_halfedge(f0, h0);
        set_halfedge(f1, h2);

        set_face(h1, f0);
        set_face(t0, f0);
        set_face(h0, f0);

        set_face(h2, f1);
        set_face(t1, f1);
        set_face(e0, f1);

        set_next_halfedge(h0, h1);
        set_next_halfedge(h1, t0);
        set_next_halfedge(t0, h0);

        set_next_halfedge(e0, h2);
        set_next_halfedge(h2, t1);
        set_next_halfedge(t1, e0);
    }
    else
    {
        set_next_halfedge(prev_halfedge(h0), t1);
        set_next_halfedge(t1, h0);
        // halfedge handle of _vh already is h0
    }


    if (!is_boundary(o0))
    {
        Halfedge o1 = next_halfedge(o0);
        Halfedge o2 = next_halfedge(o1);

        Vertex v3 = to_vertex(o1);

        Halfedge e2 = new_edge(v, v3);
        Halfedge t2 = opposite_halfedge(e2);

        Face f2 = new_face();
        set_halfedge(f2, o1);
        set_halfedge(f3, o0);

        set_face(o1, f2);
        set_face(t2, f2);
        set_face(e1, f2);

        set_face(o2, f3);
        set_face(o0, f3);
        set_face(e2, f3);

        set_next_halfedge(e1, o1);
        set_next_halfedge(o1, t2);
        set_next_halfedge(t2, e1);

        set_next_halfedge(o0, e2);
        set_next_halfedge(e2, o2);
        set_next_halfedge(o2, o0);
    }
    else
    {
        set_next_halfedge(e1, next_halfedge(o0));
        set_next_halfedge(o0, e1);
        set_halfedge(v, e1);
    }

    if (halfedge(v2) == h0)
        set_halfedge(v2, t1);
}
Beispiel #10
0
Surface_mesh::Face
Surface_mesh::
add_face(const std::vector<Vertex>& vertices)
{
    Vertex                   v;
    unsigned int             i, ii, n((int)vertices.size()), id;
    std::vector<Halfedge>    halfedges(n);
    std::vector<bool>        is_new(n), needs_adjust(n, false);
    Halfedge                 inner_next, inner_prev,
    outer_next, outer_prev,
    boundary_next, boundary_prev,
    patch_start, patch_end;

    // cache for set_next_halfedge and vertex' set_halfedge
    typedef std::pair<Halfedge, Halfedge>  NextCacheEntry;
    typedef std::vector<NextCacheEntry>    NextCache;

    NextCache    next_cache;
    next_cache.reserve(3*n);


    // don't allow degenerated faces
    assert (n > 2);


    // test for topological errors
    for (i=0, ii=1; i<n; ++i, ++ii, ii%=n)
    {
        if ( !is_boundary(vertices[i]) )
        {
            std::cerr << "Surface_meshT::add_face: complex vertex\n";
            return Face();
        }

        halfedges[i] = find_halfedge(vertices[i], vertices[ii]);
        is_new[i]    = !halfedges[i].is_valid();

        if (!is_new[i] && !is_boundary(halfedges[i]))
        {
            std::cerr << "Surface_meshT::add_face: complex edge\n";
            return Face();
        }
    }


    // re-link patches if necessary
    for (i=0, ii=1; i<n; ++i, ++ii, ii%=n)
    {
        if (!is_new[i] && !is_new[ii])
        {
            inner_prev = halfedges[i];
            inner_next = halfedges[ii];

            if (next_halfedge(inner_prev) != inner_next)
            {
                // here comes the ugly part... we have to relink a whole patch

                // search a free gap
                // free gap will be between boundary_prev and boundary_next
                outer_prev = opposite_halfedge(inner_next);
                outer_next = opposite_halfedge(inner_prev);
                boundary_prev = outer_prev;
                do
                    boundary_prev = opposite_halfedge(next_halfedge(boundary_prev));
                while (!is_boundary(boundary_prev) || boundary_prev==inner_prev);
                boundary_next = next_halfedge(boundary_prev);
                assert(is_boundary(boundary_prev));
                assert(is_boundary(boundary_next));


                // ok ?
                if (boundary_next == inner_next)
                {
                    std::cerr << "Surface_meshT::add_face: patch re-linking failed\n";
                    return Face();
                }

                // other halfedges' handles
                patch_start = next_halfedge(inner_prev);
                patch_end   = prev_halfedge(inner_next);

                // relink
                next_cache.push_back(NextCacheEntry(boundary_prev, patch_start));
                next_cache.push_back(NextCacheEntry(patch_end, boundary_next));
                next_cache.push_back(NextCacheEntry(inner_prev, inner_next));
            }
        }
    }



    // create missing edges
    for (i=0, ii=1; i<n; ++i, ++ii, ii%=n)
        if (is_new[i])
            halfedges[i] = new_edge(vertices[i], vertices[ii]);



    // create the face
    Face f(new_face());
    set_halfedge(f, halfedges[n-1]);



    // setup halfedges
    for (i=0, ii=1; i<n; ++i, ++ii, ii%=n)
    {
        v          = vertices[ii];
        inner_prev = halfedges[i];
        inner_next = halfedges[ii];

        id = 0;
        if (is_new[i])  id |= 1;
        if (is_new[ii]) id |= 2;

        if (id)
        {
            outer_prev = opposite_halfedge(inner_next);
            outer_next = opposite_halfedge(inner_prev);

            // set outer links
            switch (id)
            {
                case 1: // prev is new, next is old
                    boundary_prev = prev_halfedge(inner_next);
                    next_cache.push_back(NextCacheEntry(boundary_prev, outer_next));
                    set_halfedge(v, outer_next);
                    break;

                case 2: // next is new, prev is old
                    boundary_next = next_halfedge(inner_prev);
                    next_cache.push_back(NextCacheEntry(outer_prev, boundary_next));
                    set_halfedge(v, boundary_next);
                    break;

                case 3: // both are new
                    if (!halfedge(v).is_valid())
                    {
                        set_halfedge(v, outer_next);
                        next_cache.push_back(NextCacheEntry(outer_prev, outer_next));
                    }
                    else
                    {
                        boundary_next = halfedge(v);
                        boundary_prev = prev_halfedge(boundary_next);
                        next_cache.push_back(NextCacheEntry(boundary_prev, outer_next));
                        next_cache.push_back(NextCacheEntry(outer_prev, boundary_next));
                    }
                    break;
            }

            // set inner link
            next_cache.push_back(NextCacheEntry(inner_prev, inner_next));
        }
        else needs_adjust[ii] = (halfedge(v) == inner_next);


        // set face handle
        set_face(halfedges[i], f);
    }



    // process next halfedge cache
    NextCache::const_iterator ncIt(next_cache.begin()), ncEnd(next_cache.end());
    for (; ncIt != ncEnd; ++ncIt)
        set_next_halfedge(ncIt->first, ncIt->second);



    // adjust vertices' halfedge handle
    for (i=0; i<n; ++i)
        if (needs_adjust[i])
            adjust_outgoing_halfedge(vertices[i]);


    return f;
}
Beispiel #11
0
void Cube::set_back(int *face) {
    int positions[8] = { 2, 3, 7, 6,    // corners
                         2, 7, 10, 6 }; // edges
    set_face(face, positions);
}
Beispiel #12
0
void Cube::set_right(int *face) {
    int positions[8] = { 1, 2, 6, 5,    // corners
                         1, 6, 9, 5 };  // edges
    set_face(face, positions);
}
Beispiel #13
0
void
Surface_mesh::
garbage_collection()
{
    if (!garbage_) return;

    int  i, i0, i1,
    nV(vertices_size()),
    nE(edges_size()),
    nH(halfedges_size()),
    nF(faces_size());

    Vertex    v;
    Halfedge  h;
    Face      f;

    if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false);
    if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false);
    if (!fdeleted_) fdeleted_ = face_property<bool>("f:deleted", false);


    // setup handle mapping
    Vertex_property<Vertex>      vmap = add_vertex_property<Vertex>("v:garbage-collection");
    Halfedge_property<Halfedge>  hmap = add_halfedge_property<Halfedge>("h:garbage-collection");
    Face_property<Face>          fmap = add_face_property<Face>("f:garbage-collection");
    for (i=0; i<nV; ++i)
        vmap[Vertex(i)] = Vertex(i);
    for (i=0; i<nH; ++i)
        hmap[Halfedge(i)] = Halfedge(i);
    for (i=0; i<nF; ++i)
        fmap[Face(i)] = Face(i);



    // remove deleted vertices
    if (nV > 0)
    {
        i0=0;  i1=nV-1;

        while (1)
        {
            // find first deleted and last un-deleted
            while (!vdeleted_[Vertex(i0)] && i0 < i1)  ++i0;
            while ( vdeleted_[Vertex(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            vprops_.swap(i0, i1);

            //add
            for(unsigned int j = 0;j<map_2skel.size();j++)
            {
                if(map_2skel[j] == i0)
                    map_2skel[j] = i1;
                else if(map_2skel[j] == i1)
                    map_2skel[j] = i0;
            }
            //end
        };

        // remember new size
        nV = vdeleted_[Vertex(i0)] ? i0 : i0+1;
    }


    // remove deleted edges
    if (nE > 0)
    {
        i0=0;  i1=nE-1;

        while (1)
        {
            // find first deleted and last un-deleted
            while (!edeleted_[Edge(i0)] && i0 < i1)  ++i0;
            while ( edeleted_[Edge(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            eprops_.swap(i0, i1);
            hprops_.swap(2*i0,   2*i1);
            hprops_.swap(2*i0+1, 2*i1+1);
        };

        // remember new size
        nE = edeleted_[Edge(i0)] ? i0 : i0+1;
        nH = 2*nE;
    }


    // remove deleted faces
    if (nF > 0)
    {
        i0=0;  i1=nF-1;

        while (1)
        {
            // find 1st deleted and last un-deleted
            while (!fdeleted_[Face(i0)] && i0 < i1)  ++i0;
            while ( fdeleted_[Face(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            fprops_.swap(i0, i1);
        };

        // remember new size
        nF = fdeleted_[Face(i0)] ? i0 : i0+1;
    }


    // update vertex connectivity
    for (i=0; i<nV; ++i)
    {
        v = Vertex(i);
        if (!is_isolated(v))
            set_halfedge(v, hmap[halfedge(v)]);
    }


    // update halfedge connectivity
    for (i=0; i<nH; ++i)
    {
        h = Halfedge(i);
        set_vertex(h, vmap[to_vertex(h)]);
        set_next_halfedge(h, hmap[next_halfedge(h)]);
        if (!is_boundary(h))
            set_face(h, fmap[face(h)]);
    }


    // update handles of faces
    for (i=0; i<nF; ++i)
    {
        f = Face(i);
        set_halfedge(f, hmap[halfedge(f)]);
    }


    // remove handle maps
    remove_vertex_property(vmap);
    remove_halfedge_property(hmap);
    remove_face_property(fmap);


    // finally resize arrays
    vprops_.resize(nV); vprops_.free_memory();
    hprops_.resize(nH); hprops_.free_memory();
    eprops_.resize(nE); eprops_.free_memory();
    fprops_.resize(nF); fprops_.free_memory();

    deleted_vertices_ = deleted_edges_ = deleted_faces_ = 0;
    garbage_ = false;
}
Beispiel #14
0
void Cube::set_left(int *face) {
    int positions[8] = { 3, 0, 4, 7,    // corners
                         3, 4, 11, 7 }; // edges
    set_face(face, positions);
}
Beispiel #15
0
void
test_validity(Mesh& mesh)
{
  typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
  typedef typename boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
  typedef typename boost::graph_traits<Mesh>::face_descriptor face_descriptor;
  typedef typename boost::property_map<Mesh, CGAL::vertex_point_t>::type VPMap;
  VPMap vpmap = get(CGAL::vertex_point, mesh);
  vertex_descriptor vertices[4];
  edge_descriptor edges[4];
  vertices[0] = add_vertex(mesh);
  vertices[1] = add_vertex(mesh);
  vertices[2] = add_vertex(mesh);
  vertices[3] = add_vertex(mesh);
  
  put(vpmap, vertices[0], Point_3(0,0,0));
  put(vpmap, vertices[1], Point_3(1,0,0));
  put(vpmap, vertices[2], Point_3(1,1,0));
  put(vpmap, vertices[3], Point_3(0,1,0));
  
  edges[0] = add_edge(mesh); 
  edges[1] = add_edge(mesh); 
  edges[2] = add_edge(mesh); 
  edges[3] = add_edge(mesh); 
  
  assert(!CGAL::is_valid_halfedge_graph(mesh));
  for(int i=0; i<4; ++i)
  {
    set_target(halfedge(edges[i], mesh), vertices[i], mesh);
    set_halfedge(vertices[i], halfedge(edges[i], mesh), mesh);
  }
  
  for(int i=0; i<4; ++i)
    set_target(opposite(halfedge(edges[i], mesh), mesh), vertices[(i+1)%4], mesh);
  for(int i=0; i<4; ++i)
  {
    set_next(halfedge(edges[(i+1)%4], mesh), halfedge(edges[i], mesh), mesh);
    set_next(opposite(halfedge(edges[i], mesh), mesh), 
        opposite(halfedge(edges[(i+1)%4], mesh), mesh), mesh);
  }
  
  assert(CGAL::is_valid_halfedge_graph(mesh));
  face_descriptor faces[1];
  faces[0] = add_face(mesh);
  assert(!CGAL::is_valid_face_graph(mesh));
  
  for(int i=0; i<4; ++i)
  {
    set_face(opposite(halfedge(edges[i], mesh), mesh), faces[0], mesh);
  }
  set_halfedge(faces[0], opposite(halfedge(edges[0], mesh), mesh), mesh);
  assert(CGAL::is_valid_face_graph(mesh));
  assert(CGAL::is_valid_polygon_mesh(mesh));
  
  Mesh dummy;
  vertices[0] = add_vertex(dummy);
  vertices[1] = add_vertex(dummy);
  edges[0] = add_edge(dummy);
  set_target(halfedge(edges[0], dummy), vertices[0], dummy);
  set_halfedge(vertices[0], halfedge(edges[0], dummy), dummy);
  set_target(opposite(halfedge(edges[0], dummy), dummy), vertices[1], dummy);
  set_halfedge(vertices[1], opposite(halfedge(edges[0], dummy), dummy), dummy);
  set_next(halfedge(edges[0], dummy), opposite(halfedge(edges[0], dummy), dummy), dummy);
  set_next(opposite(halfedge(edges[0], dummy), dummy), halfedge(edges[0], dummy), dummy);
  faces[0] = add_face(dummy);
  set_halfedge(faces[0], opposite(halfedge(edges[0], dummy), dummy), dummy);
  set_face(halfedge(edges[0], dummy), faces[0], dummy);
  set_face(opposite(halfedge(edges[0], dummy), dummy), faces[0], dummy);
  assert(CGAL::is_valid_face_graph(dummy));
  assert(!CGAL::is_valid_polygon_mesh(dummy));
  
}
Beispiel #16
0
Torus :: Torus(float r, float r2, int vs, int rs)
{
	// set radii
	radius = r;
	radius2 = r2;
	
	// set stack interval
	float stack = (2 * M_PI) / vs;
	// set slice interval
	float slice = (2 * M_PI) / rs;
	
	// define the number of vertices
	verts_size = vs * rs;
	verts = new GLfloat*[verts_size];
	
	// define the number of faces
	faces_size = verts_size * 2;
	faces = new int*[faces_size];
	
	// define arrays for normals
	v_norms = new GLfloat*[verts_size];
	f_norms = new GLfloat*[faces_size];
	
	// define to keep track of faces 
	// for vertex normal calculation
	int vert_faces[verts_size];
	
	// VERTICES
	/////////////////////////////////////////////
	
	GLfloat* v;
	
	// current angle of rotation for stack
	float curr_stack;
	// current angle of rotation for slice
	float curr_slice;
	// current positions in the array
	int pos, pos2, pos3;
	
	// loop to set vertices
	for( int i = 0; i < vs; i++ )
	{
		// calculate stack angle
		curr_stack = -i * stack;
		
		for( int j = 0; j < rs; j++ )
		{
			// calculate slice angle
			curr_slice = j * slice;
			
			// calculate position in the array
			pos = i * rs + j;
			
			// allocate new vertex
			v = new GLfloat[4];
			v[0] = 0;
			v[1] = r2;
			v[2] = 0;
			v[3] = 1;
			
			// rotate by stack angle
			v_rotate_z(v, curr_stack);
			// translate to edge of the ring
			v_translate(v, r, 0.0, 0.0);
			// rotate by slice angle
			v_rotate_y(v, curr_slice);
			
			// store in verts array
			verts[pos] = v;
			// initialize vertex normal
			v_norms[pos] = new GLfloat[4];
			init_vector(v_norms[pos]);
			// initalize vertex face count
			vert_faces[pos] = 0;
		}
	}
	
	// FACES + NORMALS
	/////////////////////////////////////////////
	
	// position of face in array
	int f_pos;
	
	// first loop sets the body
	for( int i = 0; i < vs; i++ )
	{
		for( int j = 0; j < 2*(rs-1); j+= 2 )
		{
			// calculate position in the array
			pos = i * rs + j/2;
			if(i == vs-1)
			{
				pos2 = j/2;
			}
			else
			{
				pos2 = (i + 1) * rs +j/2;
			}
			pos3 = pos2 + 1;
			f_pos = i * 2 * rs + j;
			
			set_face(f_pos, pos, pos2, pos3, vert_faces);
			
			f_pos++;
			pos2++;
			pos3 = pos + 1;
			
			set_face(f_pos, pos, pos2, pos3, vert_faces);
			
		}
		
		// calculate position in the array
		pos = (i * rs)+ rs - 1;
		if(i == vs-1)
		{
			pos2 = rs - 1;
			pos3 = 0;
		}
		else
		{
			pos2 = (i + 1) * rs + rs - 1;
			pos3 = (i + 1) * rs;
		}
		f_pos++;
		
		set_face(f_pos, pos, pos2, pos3, vert_faces);
		
		f_pos++;
		if(i == vs-1)
		{
			pos2 = 0;
		}
		else
		{
			pos2 = (i+1) * rs;
		}
		pos3 = i * rs;
		
		set_face(f_pos, pos, pos2, pos3, vert_faces);
	}
	
	// VERTEX NORMALS
	/////////////////////////////////////////////
	
	// loop through vertices
	for( int i = 0; i < verts_size; i++ )
	{
		v_norms[i][0] = v_norms[i][0] / vert_faces[i];
		v_norms[i][1] = v_norms[i][1] / vert_faces[i];
		v_norms[i][2] = v_norms[i][2] / vert_faces[i];
		v_norms[i][3] = 1.0;
		normalize(v_norms[i]);
	}
	
}
Beispiel #17
0
void Cube::set_down(int *face) {
    int positions[8] = { 7, 4, 5, 6,    // corners
                         8, 9, 10, 11 };// edges
    set_face(face, positions);
}
Beispiel #18
0
void Cube::set_top(int *face) {
    int positions[8] = { 0, 3, 2, 1,    // corners
                         2, 1, 0, 3 };  // edges
    set_face(face, positions);
}