Beispiel #1
0
struct graph *init_graph(int *vertex_data, int num_vertex, int edge_data[][3], int num_edge)
{
	struct graph *graph;
	struct adj_table *adj;
	int i;

	graph = malloc(sizeof(struct graph));
	graph->v = malloc(num_vertex * sizeof(struct vertex));
	graph->e = malloc(num_edge * sizeof(struct edge));
	graph->pe = malloc(num_edge * sizeof(struct edge *));
	graph->num_vertex = num_vertex;
	graph->num_edge = num_edge;

	for (i = 0; i < num_vertex; i++) {
		graph->v[i].data = vertex_data[i];
		graph->v[i].color = WHITE;
		adj = malloc(sizeof(struct adj_table));
		graph->v[i].adj = adj;
		graph->v[i].adj->max_edge = num_edge;
		graph->v[i].adj->num_edge = 0;
		graph->v[i].adj->v = malloc(num_edge * sizeof(struct vertex *));
	}

	for (i = 0; i < num_edge; i++) {
		graph->e[i].u = find_vertex(graph, edge_data[i][0]);
		graph->e[i].v = find_vertex(graph, edge_data[i][1]);
		graph->e[i].w = edge_data[i][2];
		graph->pe[i] = &graph->e[i];
		insert_adj_table(graph->e[i].u->adj, graph->e[i].v);
	}

	return graph;
}
Beispiel #2
0
void mesh_set_average_vertex_normals(struct mesh *m)
{
	int i, j, k;
	struct vertex *vn, **v;

	v = malloc(sizeof(*v) * m->nvertices);
	vn = malloc(sizeof(*vn) * m->nvertices);

	/* Use w as a counter of how many triangles use a vertex, init to 0 */
	for (i = 0; i < m->nvertices; i++)
		m->v[i].w = 0.0;
	k = 0;
	for (i = 0; i < m->ntriangles; i++) {
		union vec3 normal;
		normal = compute_triangle_normal(&m->t[i]);
		m->t[i].n.x = normal.v.x;
		m->t[i].n.y = normal.v.y;
		m->t[i].n.z = normal.v.z;
		for (j = 0; j < 3; j++) {
			/* First time we've encountered this vertex? */
			if (m->t[i].v[j]->w < 0.5) {
				v[k] = m->t[i].v[j];
				vn[k].x = normal.v.x;
				vn[k].y = normal.v.y;
				vn[k].z = normal.v.z;
				vn[k].w = 1.0;
				m->t[i].v[j]->w = 1.0;
				k++;
			} else {
				int fv = find_vertex(v, m->t[i].v[j], m->nvertices);
				assert(fv >= 0);
				vn[fv].x += normal.v.x;
				vn[fv].y += normal.v.y;
				vn[fv].z += normal.v.z;
				vn[fv].w += 1.0;
				m->t[i].v[j]->w += 1.0;
			}
		}
	}
	for (i = 0; i < m->ntriangles; i++) {
		for (j = 0; j < 3; j++) {
			k = find_vertex(v, m->t[i].v[j], m->nvertices);
			assert(k >= 0);
			/* Average the normals... */
			m->t[i].vnormal[j].x = vn[k].x / m->t[i].v[j]->w;
			m->t[i].vnormal[j].y = vn[k].y / m->t[i].v[j]->w;
			m->t[i].vnormal[j].z = vn[k].z / m->t[i].v[j]->w;
		}
	}

	/* set w's back to 1.0 */
	for (i = 0; i < m->nvertices; i++)
		m->v[i].w = 1.0;
	free(vn);
	free(v);
}
Beispiel #3
0
int Mesh::addEdge(int a, int b)
{
	m_edge.push_back(Edge(a, b, m_edge.size(), this));
	Edge *e = &m_edge.back();
	const Vec3& av = find_vertex(e->a())->point();
	const Vec3& bv = find_vertex(e->b())->point();
	e->m_length = Vec3::distance(av, bv);
	e->m_center = (av + bv) / 2.0f;
	return e->index();
}
Beispiel #4
0
void Mesh::commitRemove()
{
	// first go over all the points and tell them where they go
	int count = 0;
	for(int i = 0; i < numVtx(); ++i)
	{
		Vertex_handle v = find_vertex(i);
		if (v->m_tran == -1)
			v->m_index = count++;
		else
			v->m_index = -1; // to be removed
		v->m_tran = -1;
	}
	// no go over the faces and transfer their point references
	count = 0;
	for(int i = 0; i < numFaces(); ++i)
	{
		Face_handle f = find_facet(i);
		bool remove = false;
		for(int ii = 0; ii < f->size(); ++ii)
		{
			int newvi = find_vertex(f->m_pi[ii])->m_index;
			f->m_pi[ii] = newvi;
			remove |= (newvi == -1);
		}
		if (!remove)
			f->m_index = count++;
		else 
			f->m_index = -1;
	}
	// actually remove the vertices
	Vertex_iterator vit = vertices_begin();
	while(vit != vertices_end())
	{
		if (vit->m_index == -1)
			vit = m_vtx.erase(vit);
		else
			++vit;
	}

	// remove faces
	Face_iterator fit = faces_begin();
	while(fit != faces_end())
	{
		if (fit->m_index == -1)
			fit = m_face.erase(fit);
		else
			++fit;
	}
}
Beispiel #5
0
Datei: gif_c.c Projekt: cran/gap
int main(int argc, char **argv)
{
  char    *progname = argv[0], *line, *newline();
  int     i, j, k, n_prob, got_opt();
  double  total_kinship();
  vertex  *top, *bot;
  blankline = &whereblank;
  line_no=0;
  for (line=newline(); line && line != blankline; line = newline())
  {
    if (sscanf(line,"%d%d%d",&i,&j,&k) != 3)
    {
      error("\n %s(%d): cannot read triplet",progname,line_no);
    }
    if (i > 0) bot = find_vertex(i);
    if (j > 0)
    {
      top = find_vertex(j);
      if (!connected(bot,top)) make_edge(bot,top);
    }
    if (k > 0)
    {
      top = find_vertex(k);
      if (!connected(bot,top)) make_edge(bot,top);
    }
  }

  for ( ; line; line=newline())
  {
    while (line && line == blankline) line=newline();
    for (no_probands(),n_prob=0 ; line && line != blankline; line=newline())
    {
      if (sscanf(line,"%d",&i) != 1)
      {
        error("\n %s(%d): cannot read integer",progname,line_no);
      }
      if (i > 0)
      {
        bot=find_vertex(i);
        if (new_proband(bot)) n_prob +=1;
      }
    }
    Rprintf("%9.3f",100000.0*total_kinship()/n_prob/(n_prob-1)*2.0);
    Rprintf("\n\n");
    R_FlushConsole();
  }
  R_ClearerrConsole();
  return(0);
}
Beispiel #6
0
void get_degrees(NETWORK *network)
{
  int s,t;
  int vs,vt;
  char *ptr;
  char line[LINELENGTH];

  reset_buffer();

  while (next_line(line)==0) {

    // Find the next edge entry

    ptr = strstr(line,"edge");
    if (ptr==NULL) continue;

    // Read the source and target of the edge

    s = t = -1;

    do {

      ptr = strstr(line,"source");
      if (ptr!=NULL) sscanf(ptr,"source %i",&s);
      ptr = strstr(line,"target");
      if (ptr!=NULL) sscanf(ptr,"target %i",&t);

      // If we see a closing square bracket we are done

      if (strstr(line,"]")!=NULL) break;

    } while (next_line(line)==0);

    // Increment the degrees of the appropriate vertex or vertices

    if ((s>=0)&&(t>=0)) {
      vs = find_vertex(s,network);
      network->vertex[vs].degree++;
      if (network->directed==0) {
	vt = find_vertex(t,network);
	network->vertex[vt].degree++;
      }
    }

  }

  return;
}
/* Deleting vertex. */
void graph_using_AL::delete_vertex(string v) {
    /* Make sure the vertex is valid. */
    map<string, set<string> >::iterator map_itr = find_vertex(v);
    if(map_itr == data.end()) return;

    /* Deleting the weights. */
    map<pair<string, string>, int>::iterator w_itr;
    for(w_itr = edge_weights.begin(); w_itr != edge_weights.end(); ) {
        if((w_itr->first.first == v) || (w_itr->first.second == v)) {
            edge_weights.erase(w_itr), w_itr = edge_weights.begin();
            continue;
        }
        w_itr++;
    }

    /* Deleting the vertex and the edges originating from the vertex. */
    data.erase(map_itr);

    /* Delete the edges to this vertex.
     * Scanning the entire list is the only option.
     */
    set<string>::const_iterator set_itr;
    for(map_itr = data.begin(); map_itr != data.end(); map_itr ++) {
        for(set_itr = map_itr->second.begin(); set_itr != map_itr->second.end(); set_itr ++) {
            if(*set_itr == v) {
                map_itr->second.erase(set_itr);
                break;
            }
        }
    }

    return;
}
/* Print the BFS tree from a particular vertex. */
void graph_using_AL::print_bfs_tree(string start_vertex, ofstream& fout) {
    /* Check if 'fout' is good. */
    assert(fout.good());

    /* Find the start vertex. */
    map<string, set<string> >::iterator v_itr = find_vertex(start_vertex);
    if(v_itr == data.end()) {
        /* Vertex not found. */
        cerr << "Start Vertex not found." << endl;
        return;
    }

    map<string, string>  parent  ;
    map<string,    int>  distance;

    /* Do the BFS traversal.
     * The 'parent' and the 'distance' containers will be populated by this function.
     */
    BFS_visit(parent, distance, start_vertex);

    /* Printing the parent details. */
    if(debug_flag) clog << "Parent array: " << endl;
    vector<pair<string, string> > vp;
    for(map<string, string>::iterator p_itr = parent.begin(); p_itr != parent.end(); p_itr++) {
        vp.push_back(pair<string, string>(p_itr->first, p_itr->second));
        if(debug_flag) cout << p_itr->first << " <-- " << p_itr->second << endl;
    }

    print_tree_with_edges_colored(vp, "red", fout);

    return;
}
bool happens_before(typename boost::graph_traits<Graph>::vertex_descriptor u,
                    typename Graph::vertex_name_type const& v_,
                    Graph const& graph) {
    typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
    boost::optional<Vertex> v = find_vertex(v_, graph);
    return v && happens_before(u, *v, graph);
}
Beispiel #10
0
bool happens_before(typename Graph::vertex_name_type const& u_,
                    VertexNameOrDescriptor const& v,
                    Graph const& graph) {
    typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
    boost::optional<Vertex> u = find_vertex(u_, graph);
    return u && happens_before(*u, v, graph);
}
Beispiel #11
0
void PhysicalSideworks::route(LogicalSideworks &logical_sideWorks){
	graph_t& lsiw_graph = logical_sideWorks.siw_graph;
	std::pair<edge_iterator,edge_iterator> p = edges(lsiw_graph);
	edge_iname_map_t eimap = get(boost::edge_iname, lsiw_graph);
	edge_oname_map_t eomap = get(boost::edge_oname, lsiw_graph);
	for(auto e = p.first; e != p.second;++e){
		LogicalFUInstance* u = logical_sideWorks.fuList[source(*e, lsiw_graph)];
		LogicalFUInstance* v = logical_sideWorks.fuList[target(*e, lsiw_graph)];
		auto cu = *find_vertex(u->correspondence()->name, siw_graph);
		auto cv = *find_vertex(v->correspondence()->name, siw_graph);
		int muxSelect = addConection(cu,cv,eomap[*e],eimap[*e]);
		v->getInputPort(eimap[*e])->setMuxSelect(u->getOutputPort(eomap[*e]),muxSelect);
		//std::cout<<*fuList[cv]->getInputPort(eimap[*e]);
	}
	//update the mux count per Datapath
	getReadXbarLuts(IResourceCostConstants::MUXCOST[IResourceCostConstants::VIRTEX5]);
}
Beispiel #12
0
Curvature Mesh::calcCurvatureFor(int vtxIndex)
{
	m_vtxCurvature.resize(numVtx());

	CCurvature_estimator ce(this);
	Vertex_handle v = find_vertex(vtxIndex);
	ce.run(v);
	return v->curvature();
}
Beispiel #13
0
void Mesh::translateCenter(const Vec3& c)
{
	for(int i = 0; i < numVtx(); ++i)
	{
		Vertex_handle v = find_vertex(i);
		v->point() -= c;
	}
	compute_bounding_box();		
	centerOfMass();
}
Beispiel #14
0
void Initialize_Single_source(struct graph *G,char s)
{
	struct vertex *t,*start;
	t=find_vertex(G,s);
	for(start=G->head;start;start=start->vertexp)
	{
		start->d=999999999;
		start->parent=NULL;
	}
	t->d=0;
}
Beispiel #15
0
Vertex
add_vertex(typename BGL_NAMED_GRAPH::vertex_name_type const& name,
           BGL_NAMED_GRAPH& g)
{
  if (optional<Vertex> vertex = find_vertex(name, g))
    /// We found the vertex, so return it
    return *vertex;
  else
    /// There is no vertex with the given name, so create one
    return add_vertex(g.vertex_constructor(name), g.derived());
}
Beispiel #16
0
float Mesh::distFromMesh(const Vec3& v)
{
	int i = m_kdtree.findNearest(v);
	Mesh::Vertex_handle vh = find_vertex(i);
	const Vec3 &cvtx = vh->point();
	float d = Vec3::distance(v, cvtx);
	Vec3 tov = cvtx - v;
	if (Vec3::dotProd(tov, vh->normal()) < 0)
		d = -d;
	return d;
}
Beispiel #17
0
int insert_edge(struct graph *G,char s,char d,int w)
{
	struct vertex *start,*end;
	start=find_vertex(G,s);
	end=find_vertex(G,d);
	(start->outdegree)++;
	(end->indegree)++;
	struct edge *temp,*node;
	node=(struct edge *)malloc(sizeof(struct edge));
	node->destin=end;
	node->next=0;
	node->weight=w;
	if(start->edgep==0)
		start->edgep=node;
	else
	{
		for(temp=start->edgep;temp->next;temp=temp->next);
		temp->next=node;
	}
	return 1;
}
Beispiel #18
0
int find_edge(struct graph *G,char s,char d)
{
	struct vertex *t;
	struct edge *temp;
	t=find_vertex(G,s);
	if(!t)
		return 0;
	for(temp=t->edgep;temp&&temp->destin->name!=d;temp=temp->next);
	if(temp)
		return 1;
	return 0;	 
}
Beispiel #19
0
void edge_delete(struct graph *G,char s,char d)
{
	struct vertex *start,*end;
	struct edge *temp,*node;
	start=find_vertex(G,s);
	end=find_vertex(G,d);
	(start->outdegree)--;
	(end->indegree)--;
	if(start->edgep->destin==end)
	{
		node=start->edgep;
		start->edgep=start->edgep->next;
		free(node);
	}
	else
	{
		for(temp=start->edgep;temp->next->destin!=end;temp=temp->next);
		node=temp->next;
		temp->next=temp->next->next;
		free(node);
	}
}
/* Deleting edge. */
void graph_using_AL::delete_edge(string from_v, string to_v) {
    map<string, set<string> >::iterator map_itr = find_vertex(from_v);
    if(map_itr == data.end()) return;

    /* Deleting the weights. */
    map<pair<string, string>, int>::iterator w_itr;
    for(w_itr = edge_weights.begin(); w_itr != edge_weights.end(); ) {
        if(d_type == directed_graph) {
            if((w_itr->first.first == from_v) && (w_itr->first.second == to_v)) {
                edge_weights.erase(w_itr), w_itr = edge_weights.begin();
                continue;
            }
        }
        else if(d_type == undirected_graph) {
            if(((w_itr->first.first == from_v) && (w_itr->first.second == to_v)) ||
                    ((w_itr->first.first == to_v) && (w_itr->first.second == from_v))
              ) {
                edge_weights.erase(w_itr), w_itr = edge_weights.begin();
                continue;
            }
        }
        w_itr++;
    }

    set<string>::iterator set_itr = map_itr->second.find(to_v);
    if(set_itr == map_itr->second.end()) return;
    map_itr->second.erase(set_itr);

    /* If it is not a directed graph, an extra deletion needs to be done. */
    if((d_type == undirected_graph) && (from_v != to_v)) {
        map_itr = find_vertex(to_v);
        assert(map_itr != data.end());
        set_itr = map_itr->second.find(from_v);
        map_itr->second.erase(set_itr);
    }

    return;
}
Beispiel #21
0
Datei: gif_c.c Projekt: cran/gap
void gif_c(int *data, int *famsize, int *gifset, int *giflen, double *gifval)
{
  int     id, i, j, k, n_prob;
  double  total_kinship();
  vertex  *top, *bot;

  top=bot=NULL;
  for (id=0; id<*famsize; id++)
  {
    i=data[id*3];
    j=data[id*3+1];
    k=data[id*3+2];
    if (i > 0) bot = find_vertex(i);
    if (j > 0)
    {
      top = find_vertex(j);
      if (!connected(bot,top)) make_edge(bot,top);
    }
    if (k > 0)
    {
      top = find_vertex(k);
      if (!connected(bot,top)) make_edge(bot,top);
    }
  }
  no_probands();
  n_prob=0;
  for (id=0;id<*giflen;id++)
  {
    i=gifset[id];
    if (i > 0)
    {
      bot=find_vertex(i);
      if (new_proband(bot)) n_prob +=1;
    }
  }
  *gifval=100000.0*total_kinship()/n_prob/(n_prob-1)*2.0;

}
Beispiel #22
0
// going to eat that vector
int Mesh::addFaceTriangulate(Mesh::TIndexList& f)
{
	if (f.size() < 3)
		return 0;

	int count = 0;
	while (1)
	{
		if (f.size() == 3)
		{
			addTriangle(f[0], f[1], f[2]);
			return ++count;
		}
		
		float mind = FLT_MAX;
		int minstart = -1;
		for(int tt = 0; tt < f.size(); ++tt)
		{
			int other = (tt + 2) % f.size();
			float d = Vec3::distance(find_vertex(f[tt])->point(), find_vertex(f[other])->point());
			if (d < mind)
			{
				mind = d;
				minstart = tt;
			}
		}
		int o1 = (minstart + 1) % f.size(), o2 = (minstart + 2) % f.size();
		addTriangle(f[minstart], f[o1], f[o2]);
		++count;
		TIndexList left;
		for(int tt = (minstart + 2) % f.size(); tt != (minstart + 1) % f.size(); tt = (tt + 1)%f.size())
			left.append(f[tt]);

		f = left;
	}

}
int main()
{
    char buffer[128], name[128];
    struct vertex *adj_list = NULL;
    int i, num_vertices, index;
    
    printf("Enter the number of vertices: ");
    fgets(buffer, 127, stdin);
    sscanf(buffer, "%d", &num_vertices);
    adj_list = malloc(sizeof(struct vertex) * num_vertices);
    if(adj_list == NULL)
    {
        printf("Memory allocation failure...\n");
        exit(-1);
    }
    for(i=0; i<num_vertices; ++i)
    {
        printf("Enter the name of vertex: ");
        fgets(buffer, 127, stdin);
        sscanf(buffer, "%[^\n]s", name);
        adj_list[i].name = malloc(strlen(name)+1);
        strcpy(adj_list[i].name, name);
        adj_list[i].e = NULL;
    }
    
    /*Add the edges to the vertices*/
    for(i=0; i<num_vertices; ++i)
    {
        printf("Enter all edges for %s (-1 to stop)\n", adj_list[i].name);
        while(1)
        {
            fgets(buffer, 127, stdin);
            sscanf(buffer, "%s", name);
            if(!strcmp(name, "-1"))
                break;
            index = find_vertex(name, adj_list, num_vertices);
            if(index == -1)
            {
                printf("Vertex with name %s does not exist. Try again.\n", name);
                continue;
            }
            add_edge(&adj_list[i], &adj_list[index]);
        }
    }
    
    display_adj_list(adj_list, num_vertices);
    
    return 1;
}
Beispiel #24
0
// compute average edge length around a vertex
float Mesh::min_edge_length_around(Vertex_handle pVertex)
{
	float min_edge_length = FLT_MAX;

	Mesh::TIndexList circVtx = pVertex->neiVertices();
	for(int i = 0; i < circVtx.size(); ++i)
	{
		Mesh::Vertex_handle cVertex = find_vertex(circVtx[i]);
		Vec3 vec = pVertex->point() - cVertex->point();
		float len = vec.length();
		if (len < min_edge_length)
			min_edge_length = len;
	}
	return min_edge_length;
}
Beispiel #25
0
void Mesh::dijkstra(Mesh::Vertex_handle v)
{
	for (Mesh::Vertex_iterator it = vertices_begin(); it != vertices_end(); ++it)
	{
		it->distance(FLT_MAX);
		//it->m_visited = false;
	}

	TVertexDistanceHeap vdh;

	int sanityCounter = 0;

	v->distance(0.0);	
	vdh.push(v);
	do {
		Mesh::Vertex_handle t = vdh.top();
		vdh.pop();
		//t->visited = true;

		TIndexList vnei = t->neiVertices();

		for (int vii = 0; vii < vnei.size(); ++vii)
		{
			Mesh::Vertex_handle n = find_vertex(vnei[vii]);
			float alt = t->distance() + Vec3::distance(t->point(), n->point());
			if (alt < n->distance()) 
			{
				n->distance() = alt;
				// we don't have the edge
				// not using closeness.
				vdh.push(n);
			}
		}

		sanityCounter++;

// 		if (sanityCounter > size_of_vertices() * 2)
// 		{
// 			printf("dijkstra sanity failed!\n");
// 			break;
// 		}
	} while (!vdh.empty());
}
Beispiel #26
0
void Mesh::rescaleAndCenter(float destdialen)
{
	Vec3 dia = m_max - m_min;
	Vec3 center = (m_max + m_min) / 2.0;

	float dialen = qMax(dia.x, dia.y);
	float scale = destdialen/dialen;

	for(int i = 0; i < numVtx(); ++i)
	{
		Vertex_handle v = find_vertex(i);
		Vec3 &p = v->point();
		p -= center;
		p *= scale;
	}

	compute_bounding_box();		
	centerOfMass();
}
Beispiel #27
0
bool Mesh::find_faces_with(int vi1, int vi2, TIndexList& res) const
{
	Vertex_const_handle v1 = find_vertex(vi1);
	TIndexList resa, resb;
	res.clear();
	for(int i = 0; i < v1->numFaces(); ++i)
	{
		Face_const_handle f = v1->face(i);
		int fi = f->containsVtx(vi2);
		if (fi != -1)
		{ // what order are the indexes
			if (f->vertexIndex((fi + 1)%3) == vi1)
				resa.append(v1->faceIndex(i));
			else
				resb.append(v1->faceIndex(i));

		}
	}
	res = resa + resb;
	return (res.size() == 2); // could be more or less than 2. return true if 2, this is the condition that it's a regular mesh.
}
Beispiel #28
0
void Mesh::calcDotCurve()
{
	m_vtxDotCurve.resize(numVtx());
	for(Vertex_iterator it = vertices_begin(); it != vertices_end(); ++it)
	{
		Vertex_handle vh = &*it;
		TIndexList nei = vh->neiVertices();
		int negdot = 0;
		float dotsum = 0.0f;
		for(int i = 0; i < nei.size(); ++i)
		{
			Vertex_handle vc = find_vertex(nei[i]);
			Vec3 vv = vc->point() - vh->point();
			vv.unitize();
		//	if (Vec3::dotProd(vv, vh->normal()) < 0.0f)
		//		++negdot;
			dotsum += Vec3::dotProd(vv, vh->normal());
		}
		//vh->dotCurve() = (((float)nei.size() / 2.0) - negdot) / (float)nei.size();
		vh->dotCurve() = dotsum;
		
	}

}
Beispiel #29
0
 unsigned int find_vertex_id(graph_t_ptr g, const std::string& name) {
   vertex_id_t vertexID=find_vertex(g, name);
   vertex_t & vertex = (*g)[vertexID];
   return vertex.id;
 }
Beispiel #30
0
vector<Segment> Shape::getCutlines(const Matrix4d &T, double z,
				   vector<Vector2d> &vertices,
				   double &max_gradient,
				   vector<Triangle> &support_triangles,
				   double supportangle,
				   double thickness) const
{
  Vector2d lineStart;
  Vector2d lineEnd;
  vector<Segment> lines;
  // we know our own tranform:
  Matrix4d transform = T * transform3D.transform ;

  int count = (int)triangles.size();
// #ifdef _OPENMP
// #pragma omp parallel for schedule(dynamic)
// #endif
  for (int i = 0; i < count; i++)
    {
      Segment line(-1,-1);
      int num_cutpoints = triangles[i].CutWithPlane(z, transform, lineStart, lineEnd);
      if (num_cutpoints == 0) {
	if (supportangle >= 0 && thickness > 0) {
	  if (triangles[i].isInZrange(z-thickness, z, transform)) {
	    const double slope = -triangles[i].slopeAngle(transform);
	    if (slope >= supportangle) {
	      support_triangles.push_back(triangles[i].transformed(transform));
	    }
	  }
	}
	continue;
      }
      if (num_cutpoints > 0) {
	int havev = find_vertex(vertices, lineStart);
	if (havev >= 0)
	  line.start = havev;
	else {
	  line.start = vertices.size();
	  vertices.push_back(lineStart);
	}
	if (abs(triangles[i].Normal.z()) > max_gradient)
	  max_gradient = abs(triangles[i].Normal.z());
	if (supportangle >= 0) {
	  const double slope = -triangles[i].slopeAngle(transform);
	  if (slope >= supportangle)
	    support_triangles.push_back(triangles[i].transformed(transform));
	}
      }
      if (num_cutpoints > 1) {
	int havev = find_vertex(vertices, lineEnd);
	if (havev >= 0)
	  line.end = havev;
	else {
	  line.end = vertices.size();
	  vertices.push_back(lineEnd);
	}
      }
      // Check segment normal against triangle normal. Flip segment, as needed.
      if (line.start != -1 && line.end != -1 && line.end != line.start)
	{ // if we found a intersecting triangle
	  Vector3d Norm = triangles[i].transformed(transform).Normal;
	  Vector2d triangleNormal = Vector2d(Norm.x(), Norm.y());
	  Vector2d segment = (lineEnd - lineStart);
	  Vector2d segmentNormal(-segment.y(),segment.x());
	  triangleNormal.normalize();
	  segmentNormal.normalize();
	  if( (triangleNormal-segmentNormal).squared_length() > 0.2){
	    // if normals do not align, flip the segment
	    int iswap=line.start;line.start=line.end;line.end=iswap;
	  }
	  // cerr << "line "<<line.start << "-"<<line.end << endl;
	  lines.push_back(line);
	}
    }
  return lines;
}