Example #1
0
rtz_vtxlst_t
rotz_get_edges(rotz_t ctx, rtz_vtx_t from)
{
	rtz_edgkey_t sfrom = rtz_edgkey(from);
	const_vtxlst_t el;
	rtz_vtx_t *d;

	/* get edges under */
	if (UNLIKELY((el = get_edges(ctx, sfrom)).d == NULL)) {
		return (rtz_vtxlst_t){0U};
	}
	/* otherwise make a copy */
	{
		size_t mz = el.z * sizeof(*d);
		d = malloc(mz);
		memcpy(d, el.d, mz);
	}
	return (rtz_vtxlst_t){.z = el.z, .d = d};
}

size_t
rotz_get_nedges(rotz_t ctx, rtz_vtx_t from)
{
	rtz_edgkey_t sfrom = rtz_edgkey(from);

	return get_edges(ctx, sfrom).z;
}
Example #2
0
int main(int argc, const char * argv[])
{




    for(double i = 2; i<100; i = i+5) {

        std::cout << "Reading file " <<std::endl;
        std::vector<edge> edges = get_edges(filename, i, 10);
        std::vector<edge> copy = get_edges(filename, i, 10);
        std::cout << edges.size() << std::endl;
        std::cout <<"creating compatabilities" << std::endl;
        cv::Mat_<double> m = create_compatabilities(edges);
        std::cout << "Core algorithm " <<std::endl;
        for(int j =0; j<40; j++) {
            bundle_iteration(edges, copy, 10, m);
            bundle_iteration(copy, edges, 10, m);
            std::cout << j << std::endl;

        }

        std::cout << "Draw results: ";

        std::stringstream file_name;

        file_name << "/Users/jrramey11/Desktop/ForcedEdge/" << i << ".png";
        std::cout << file_name.str() << std::endl;
        draw_and_show_edges(edges,file_name.str());
    }

    for(double i = 125; i<1000; i = i+25) {
        std::cout << "Reading file " <<std::endl;
        std::vector<edge> edges = get_edges(filename, i, 10);
        std::vector<edge> copy = get_edges(filename, i, 10);

        std::cout <<"creating compatabilities" << std::endl;
        cv::Mat_<double> m = create_compatabilities(edges);
        std::cout << "Core algorithm " <<std::endl;
        for(int j =0; j<40; j++) {
            bundle_iteration(edges, copy, 10, m);
            bundle_iteration(copy, edges, 10, m);
            std::cout << j << std::endl;

        }

        std::cout << "Draw results: ";

        std::stringstream file_name;

        file_name << "/Users/jrramey11/Desktop/ForcedEdge/" << i << ".png";
        std::cout << file_name.str() << std::endl;
        draw_and_show_edges(edges,file_name.str());
    }

    return 0;
}
// ---------------------------------------------------------------------------
//
// ------------
int bXMapNetClean::join_on_edges(bArray& loop, int* fields, bool report){
_bTrace_("bXMapNetClean::join_on_edges",true);
bGenericGeoElement	*oa,*ob;
ivertices			*vsa,*vsb;
i2dvertex			vx,vmin;
bArray				edg(sizeof(bGenericGeoElement*));
bArray				bdg(sizeof(bGenericGeoElement*));
double				dte,dab;
bool				flg;
char				msg[__MESSAGE_STRING_LENGTH_MAX__];
char				ttl[__MESSAGE_STRING_LENGTH_MAX__];
    
    get_localized_name(ttl,getbundle());

    b_message_string(kXMapNetCleanJoinOnEdgesMessage,msg,getbundle(),0);
bProgressWait	wt(ttl,msg,true,true,loop.count());
    for(long i=1;i<=loop.count();i++){
        if(!wt.set_progress(i)){
            break;
        }
        loop.get(i,&oa);
        oa->getVertices(&vsa);
        get_bridges(&vsa->vx.vx2[0],bdg);
        if(bdg.count()!=0){
            continue;
        }
        get_edges(&vsa->vx.vx2[0],edg,true);
        flg=(edg.count()>0);
        for(long j=1;j<=edg.count();j++){
            edg.get(j,&ob);
            ob->getVertices(&vsb);
            dte=ivx2_dist(&vsa->vx.vx2[0],&vsb->vx.vx2[0]);
            dab=ivx2_dist(&vsa->vx.vx2[0],&vsb->vx.vx2[vsb->nv-1]);
            if(dte<dab){
                vx=vsb->vx.vx2[0];
            }
            else{
                vx=vsb->vx.vx2[vsb->nv-1];
            }
            if(j==1){
                vmin=vx;
            }
            else{
                if(!eq_ivx2(&vmin,&vx)){
                    flg=false;
                    break;
                }
            }
        }
        if(!flg){
            continue;
        }
        vsa->vx.vx2[0]=vmin;
        oa->setVertices(vsa);
        if(report){
            set_net_flag(oa,fields[oa->getType()-1],_kNodeJoined);
        }
    }
    return(0);
}
Example #4
0
//computes the surface norms of a mesh
void get_surface_norms(jmesh *jm){

    //must have a vector for each vertex and for each face
    jm->normals = malloc((3*jm->nvert+3*jm->ntri)*sizeof(float));

    float edges[6]; //will hold two edge vectors
    float normal[3];//will hold the cross product of edges
    float len;
    for(int i=0; i < jm->ntri; i++){
        get_edges(jm, i, edges);
        cross_product(edges, normal);

        //normalize the cross-product
        len = length(normal);
        normal[0] = normal[0]/len;
        normal[1] = normal[1]/len;
        normal[2] = normal[2]/len;

        //put the normalized vector into jm

        *getSurfaceNormX(jm, i) = normal[0];
        *getSurfaceNormY(jm, i) = normal[1];
        *getSurfaceNormZ(jm, i) = normal[2];

    }
}
Example #5
0
double ConnectivityRestraint::unprotected_evaluate(
    DerivativeAccumulator *accum) const {
  IMP_CHECK_OBJECT(ps_.get());
  IMP_OBJECT_LOG;
  base::Vector<Edge> mst;
  if (!sc_) return 0;
  kernel::ParticleIndexPairs edges = get_edges(sc_, ps_);
  return ps_->evaluate_indexes(get_model(), edges, accum, 0, edges.size());
}
// ---------------------------------------------------------------------------
//
// ------------
int bXMapNetClean::check_edges(bArray& loop, int* fields){
_bTrace_("bXMapNetClean::check_edges",true);
bGenericGeoElement	*oa;
ivertices			*vsa;
bArray				arra(sizeof(bGenericGeoElement*));
bArray				arrb(sizeof(bGenericGeoElement*));
double				dbk=_cfg_prm.dnod;
char				msg[__MESSAGE_STRING_LENGTH_MAX__];
char				ttl[__MESSAGE_STRING_LENGTH_MAX__];
    
    _cfg_prm.dnod=0;
    
    get_localized_name(ttl,getbundle());

    b_message_string(kXMapNetCleanCheckEdgesMessage,msg,getbundle(),0);
bProgressWait	wt(ttl,msg,true,true,loop.count());
    for(long i=1;i<=loop.count();i++){
        if(!wt.set_progress(i)){
            break;
        }
        loop.get(i,&oa);
        oa->getVertices(&vsa);
        
        get_edges(&vsa->vx.vx2[0],arra,true);
        get_edges(&vsa->vx.vx2[vsa->nv-1],arrb,true);
        if((arra.count()==1)&&(arrb.count()==1)){
            set_net_flag(oa,fields[oa->getType()-1],_kEdgeAlone);
        }
        else if((arra.count()==1)||(arrb.count()==1)){
            set_net_flag(oa,fields[oa->getType()-1],_kEdgeDeadEnd);
        }
        
        get_nodes(&vsa->vx.vx2[0],arra);
        get_nodes(&vsa->vx.vx2[vsa->nv-1],arrb);
        if((arra.count()==0)||(arrb.count()==0)){
            set_net_flag(oa,fields[oa->getType()-1],_kEdgeNotJoined);
        }
    }
    
    _cfg_prm.dnod=dbk;
    
    return(0);
}
Example #7
0
    std::string to_str() const {
        std::string output;

        output += "Edges: " + std::to_string(get_edges()) + " Source: " + std::to_string(source) + " Target: " + std::to_string(target) + "\n";
        for (std::size_t i = 0; i < edge_vec.size(); ++i) {
            output += edge_vec[i].get_str() + "\n";
        }

        output += "Vertices: " + std::to_string(get_vertices());
        return output;
    }
Example #8
0
rtz_wtxlst_t
rotz_munion(rotz_t cp, rtz_wtxlst_t x, rtz_vtx_t v)
{
	rtz_edgkey_t vkey = rtz_edgkey(v);
	const_vtxlst_t el;

	if (UNLIKELY((el = get_edges(cp, vkey)).d == NULL)) {
		return x;
	}
	/* just add them one by one */
	return wtxlst_union(x, el);
}
std::list<Edge> Graph::get_edges_to(Vertex vertex) {
  // Create the predicate functor, todo make efficient.
  struct has_vertex {
    Vertex& vertex;
    has_vertex(Vertex& vertex) : vertex(vertex) {}
    bool operator()(const Edge& edge) {
      return edge.dest != vertex.uid;
    }
  };
  // Retrieve the edges.
  std::list<Edge> edges = get_edges();
  // Remove the components of the edge we don't.
  edges.remove_if(has_vertex(vertex));
  // Rteturn the edge.
  return edges;
}
Example #10
0
int
rotz_add_edge(rotz_t ctx, rtz_vtx_t from, rtz_vtx_t to)
{
	rtz_edgkey_t sfrom = rtz_edgkey(from);
	const_vtxlst_t el;

	/* get edges under */
	if ((el = get_edges(ctx, sfrom)).d != NULL &&
	    UNLIKELY(find_in_vtxlst(el, to) > 0U)) {
		/* to is already there */
		return 0;
	}
	if (UNLIKELY(add_edge(ctx, sfrom, to) < 0)) {
		return -1;
	}
	return 1;
}
Example #11
0
static const_vtxlst_t
rem_from_vtxlst(const_vtxlst_t el, size_t idx)
{
	static rtz_vtx_t *edgspc;
	static size_t edgspz;
	rtz_vtx_t *ep;

	if (UNLIKELY(el.z * sizeof(*edgspc) > edgspz)) {
		edgspz = ((el.z * sizeof(*edgspc) - 1) / 64U + 1U) * 64U;
		edgspc = realloc(edgspc, edgspz);
	}
	/* IDX points to the elements after the deletee
	 * so IDX - 1 points to the deletee and
	 * if IDX - 1 > 0 then [0, IDX - 1) are the elements before */
	ep = edgspc;
	if (idx - 1U) {
		memcpy(ep, el.d, (idx - 1U) * sizeof(*el.d));
		ep += idx - 1U;
	}
	if (idx < el.z) {
		el.d += idx;
		el.z -= idx;
		memcpy(ep, el.d, el.z * sizeof(*el.d));
		ep += el.z;
	}
	return (const_vtxlst_t){.z = ep - edgspc, .d = edgspc};
}

/* API */
int
rotz_get_edge(rotz_t ctx, rtz_vtx_t from, rtz_vtx_t to)
{
	rtz_edgkey_t sfrom = rtz_edgkey(from);
	const_vtxlst_t el;

	/* get edges under */
	if (LIKELY((el = get_edges(ctx, sfrom)).d != NULL) &&
	    LIKELY(find_in_vtxlst(el, to) > 0U)) {
		/* to is already there */
		return 1;
	}
	return 0;
}
Example #12
0
int
rotz_rem_edge(rotz_t ctx, rtz_vtx_t from, rtz_vtx_t to)
{
	rtz_edgkey_t sfrom = rtz_edgkey(from);
	const_vtxlst_t el;
	size_t idx;

	/* get edges under */
	if (UNLIKELY((el = get_edges(ctx, sfrom)).d == NULL) ||
	    UNLIKELY((idx = find_in_vtxlst(el, to)) == 0U)) {
		/* TO isn't in there */
		return 0;
	}
	if (UNLIKELY((el = rem_from_vtxlst(el, idx)).d == NULL)) {
		/* huh? */
		return -1;
	}
	add_vtxlst(ctx, sfrom, el);
	return 1;
}
/*
 * 克鲁斯卡尔(Kruskal)最小生成树
 */
void kruskal(Graph G)
{
    int i,m,n,p1,p2;
    int length;
    int index = 0;          // rets数组的索引
    int vends[MAX]={0};     // 用于保存"已有最小生成树"中每个顶点在该最小树中的终点。
    EData rets[MAX];        // 结果数组,保存kruskal最小生成树的边
    EData *edges;           // 图对应的所有边

    // 获取"图中所有的边"
    edges = get_edges(G);
    // 将边按照"权"的大小进行排序(从小到大)
    sorted_edges(edges, G.edgnum);

    for (i=0; i<G.edgnum; i++)
    {
        p1 = get_position(G, edges[i].start);   // 获取第i条边的"起点"的序号
        p2 = get_position(G, edges[i].end);     // 获取第i条边的"终点"的序号

        m = get_end(vends, p1);                 // 获取p1在"已有的最小生成树"中的终点
        n = get_end(vends, p2);                 // 获取p2在"已有的最小生成树"中的终点
        // 如果m!=n,意味着"边i"与"已经添加到最小生成树中的顶点"没有形成环路
        if (m != n)
        {
            vends[m] = n;                       // 设置m在"已有的最小生成树"中的终点为n
            rets[index++] = edges[i];           // 保存结果
        }
    }
    free(edges);

    // 统计并打印"kruskal最小生成树"的信息
    length = 0;
    for (i = 0; i < index; i++)
        length += rets[i].weight;
    printf("Kruskal=%d: ", length);
    for (i = 0; i < index; i++)
        printf("(%c,%c) ", rets[i].start, rets[i].end);
    printf("\n");
}
void Kruskal(LGraph G)
{
	int p1, p2;
	int m, n;
	int index = 0;
	int vends[MAXN] = {0};	//用于保存"已有最小生成树"中每个顶点在该最小树中的终点。
							//for ex:已经有一条边AB了,那么vends[A.pos] = B.pos
	EData rets[MAXN];		//结果数组,保存生成树的边
	EData *edges;			//图对应的所有边
	
	edges = get_edges(G);
	sort_edges(edges, G.edgnum);

	for (int i = 0; i < G.edgnum; ++i)
	{
		p1 = getPos(G, edges[i].start);
		p2 = getPos(G, edges[i].end);

		m = get_end(vends, p1);
		n = get_end(vends, p2);
		//m != n说明没有形成环
		if (m != n)
		{
			vends[m] = n;
			rets[index++] = edges[i];
		}
	}
	free(edges);

	int length = 0;
	for (int i = 0; i < index; ++i)
		length += rets[i].weight;
	printf("Kruskal = %d: ", length);
	for (int i = 0; i < index; ++i)
		printf("(%c, %c) ", rets[i].start, rets[i].end);
	printf("\n");
	
}
Example #15
0
ParticlePairsTemp ConnectivityRestraint::get_connected_pairs() const {
  IMP_CHECK_OBJECT(ps_.get());
  kernel::ParticleIndexPairs edges = get_edges(sc_, ps_);
  return IMP::internal::get_particle(get_model(), edges);
}
Example #16
0
/* find the lowest cost path and mark it on the map */
void make_path(struct map *map,
	int x0, int y0, int x1, int y1)
{
    int start, end, cost, i, index, mdistance;
    pq_t * pq;
    int edges[4];
    
    pq = pq_create();
    cost = 0;
    start = y0 * map->width + x0;
    end = y1 * map->width + x1;
    
    
    map->grid[start].flags |= SQ_FLAG_START;
    map->grid[end].flags |= SQ_FLAG_GOAL;
    
    map->grid[start].glyph = 'A';
    map->grid[end].glyph = 'B';
    
    if(map->grid[start].cost == -1 || map->grid[end].cost == -1)
    {
        map->cost = -1;
        return;
    }
    

    
    
    curses_draw_map(map);
    
    mdistance = man_distance(start, end, map);
    if(!pq_enqueue(pq, start, map->grid[start].cost
                            + mdistance)) exit(EXIT_FAILURE);
    
    
    while(1)
    {
        if(!pq_dequeue(pq, &index, &cost)) exit(EXIT_FAILURE);
        if(map->grid[index].parent)
            
        
/*
 * Kill two birds with one stone (Visited == enqueued in this case)
*/
        map->grid[index].flags |= SQ_FLAG_VISITED;
        map->grid[index].flags &= ~SQ_FLAG_ENQUEUED;
        
        if(index == end) break;
        get_edges(index, edges, map);
        
        curses_draw_map(map);
        
        for(i = 0; i < 4; i++)
        {
            
            if(edges[i] != -1)
            {
                map->grid[edges[i]].parent = index;
                
                mdistance = man_distance(edges[i], end, map);
                
                if(!pq_enqueue(pq, edges[i], 
                        (cost) + map->grid[edges[i]].cost))
                    exit(EXIT_FAILURE);
                
                map->grid[edges[i]].flags |= SQ_FLAG_ENQUEUED;
                map->grid[edges[i]].flags |= SQ_FLAG_VISITED;
            }
        }
               
    }
    
/*
 * This next section will fill the path array in the map struct by iterating
 * through the path found in the above code, which is done by following each
 * node's parent.
 * It will begin with setting the total cost of the path to the cost of the
 * end node, then working backwards towards the start node which has a zero cost
 * (which is actually appended to the total cost).
 * It will then begin iteration, setting the glyph and flags, then setting the 
 * start and end node's glyphs, as these will be set with 'o' during the loop.
 * If the start and the end have the same coordinates, there will be a zero cost
 * because the only node which is appended to the total is the end, which is
 * the start, which has a zero cost.
*/
    
    i = end;
    

    
/*
 * Instantiate the path array
*/
    map->path = safe_malloc(map->width * map->height * sizeof(int));
    map->path_index = 0;
    map->cost = -1;
    
/*
 * Dont include the start node's cost in the calculation
*/
    map->grid[start].cost = 0;
    
/*
 * Make sure the start node's parent is 0;
 * 
*/
    map->grid[start].parent = 0;
    map->cost = map->grid[i].cost;
    
    while(map->grid[i].parent)
    {
/*
     This will miss the start node, therefore we will append it after the loop   
*/
        map->grid[i].flags |= SQ_FLAG_PATH;
        map->grid[i].glyph = 'o';
        map->path[map->path_index++] = i;
        i = map->grid[i].parent;
        map->cost += map->grid[i].cost;
    }
    map->path[map->path_index++] = i;
    
   
    map->grid[start].glyph = 'A';
    map->grid[end].glyph = 'B';
    
    curses_draw_map(map);
    pq_destroy(pq);
    
	
}	
Example #17
0
std::string MLNetwork::to_string() const {
	return "Multilayer Network (\"" + name + "\": " + std::to_string(get_layers().size()) + " layers, " +
			std::to_string(get_actors().size()) + " actors, " +
			std::to_string(get_nodes().size()) + " nodes, " +
			std::to_string(get_edges().size()) + " edges)";
}
// ---------------------------------------------------------------------------
//
// ------------
int bXMapNetClean::create_nodes(bArray& loop, bArray& added, int* fields, bool report){
_bTrace_("bXMapNetClean::create_nodes",true);
    if(!_cfg_prm.tnod){
        return(0);
    }
bGenericGeoElement	*oa,*ob,*op;
ivertices			*vsa,*vsb,*vsp;
i2dvertex			vx;
ivx_rect			vxr;
bArray				edg(sizeof(bGenericGeoElement*));
bArray				bdg(sizeof(bGenericGeoElement*));
bArray				nod(sizeof(bGenericGeoElement*));
char				msg[__MESSAGE_STRING_LENGTH_MAX__];
char				ttl[__MESSAGE_STRING_LENGTH_MAX__];
    
    
    vsp=ivs_new(_2D_VX,1,0);
    
    get_localized_name(ttl,getbundle());
    b_message_string(kXMapNetCleanNodeCreationMessage,msg,getbundle(),0);
bProgressWait	wt(ttl,msg,true,true,loop.count());
    for(long i=1;i<=loop.count();i++){
        if(!wt.set_progress(i)){
            break;
        }
        loop.get(i,&oa);
        oa->getVertices(&vsa);
        
        get_nodes(&vsa->vx.vx2[0],nod);
        if(nod.count()==0){
            _cfg_prm.tnod->new_object(&op);
            vsp->vx.vx2[0]=vsa->vx.vx2[0];
            op->setVertices(vsp);
            op->setSubType(_cfg_prm.stnod);
            op->setName(_cfg_prm.name);
            if(report){
                set_net_flag(op,fields[_cfg_prm.tnod->index()-1],_kNodeCreated);
            }
            added.add(&op);
        }
        
        get_nodes(&vsa->vx.vx2[vsa->nv-1],nod);
        if(nod.count()==0){
            _cfg_prm.tnod->new_object(&op);
            vsp->vx.vx2[0]=vsa->vx.vx2[vsa->nv-1];
            op->setVertices(vsp);
            op->setSubType(_cfg_prm.stnod);
            op->setName(_cfg_prm.name);
            if(report){
                set_net_flag(op,fields[_cfg_prm.tnod->index()-1],_kNodeCreated);
            }
            added.add(&op);
        }
        
        oa->getBounds(&vxr);
        get_edges(&vxr,edg);
        for(long j=1;j<=edg.count();j++){
            edg.get(j,&ob);
            if(oa==ob){
                continue;
            }
            
            ob->getVertices(&vsb);
            for(long k=0;k<vsa->nv-1;k++){
                for(long l=0;l<vsb->nv-1;l++){
                    if(ivx2_sect(	&vsa->vx.vx2[k],
                                    &vsa->vx.vx2[k+1],
                                    &vsb->vx.vx2[l],
                                    &vsb->vx.vx2[l+1])){
                        ivx2_get_sect(	&vsa->vx.vx2[k],
                                        &vsa->vx.vx2[k+1],
                                        &vsb->vx.vx2[l],
                                        &vsb->vx.vx2[l+1],
                                        &vx);
                        
                        get_bridges(&vx,bdg);
                        if(bdg.count()>0){
                            continue;
                        }
                        get_nodes(&vx,nod);
                        if(nod.count()>0){
                            nod.get(1,&op);
                            added.add(&op);
                            continue;
                        }
                        _cfg_prm.tnod->new_object(&op);
                        vsp->vx.vx2[0]=vx;
                        op->setVertices(vsp);
                        op->setSubType(_cfg_prm.stnod);
                        op->setName(_cfg_prm.name);
                        if(report){
                            set_net_flag(op,fields[_cfg_prm.tnod->index()-1],_kNodeCreated);
                        }
                        added.add(&op);
                    }
                }
            }
        }
    }
    
    ivs_free(vsp);
    
    return(0);
}
// ---------------------------------------------------------------------------
//
// ------------
int bXMapNetClean::cut_edges(bArray& loop, bArray& added, int* fields, bool report){
_bTrace_("bXMapNetClean::cut_edges",true);
bGenericGeoElement	*oa,*ob,*op;
bGenericType		*tp;
ivertices			*vsa,*vsb,*vse,*vsp;
bArray				edg(sizeof(bGenericGeoElement*));
bArray				bdg(sizeof(bGenericGeoElement*));
int                 k;
double				d,r;
i2dvertex			vr;
char				msg[__MESSAGE_STRING_LENGTH_MAX__];
char				ttl[__MESSAGE_STRING_LENGTH_MAX__];
    
    get_localized_name(ttl,getbundle());

    b_message_string(kXMapNetCleanCutEdgesMessage,msg,getbundle(),0);
bProgressWait	wt(ttl,msg,true,true,loop.count());
    for(long i=1;i<=loop.count();i++){
        if(!wt.set_progress(i)){
            break;
        }
        loop.get(i,&op);
        op->getVertices(&vsp);
        get_bridges(&vsp->vx.vx2[0],bdg);
        if(bdg.count()>0){
_tm_("bridge");
            continue;
        }
        
        get_edges(&vsp->vx.vx2[0],edg,false);
        for(long j=1;j<=edg.count();j++){
            edg.get(j,&oa);
            oa->getVertices(&vsa);
            d=ivx_proj(&vsp->vx.vx2[0],
                       vsa,
                       &vr,
                       &k,
                       &r);
            if(ivs2ivs(vsa,&vse)){
_te_("ivs2ivs failed");
                continue;
            }
            vsa=NULL;
            vsb=NULL;
            vse=ivx2_insert(vse,&vr,k);
            if((k==0)||(k==vse->nv-1)){
                ivs_free(vse);
                continue;
            }
            ivs_split(vse,k,&vsa,&vsb);
            if((!vsa)||(!vsb)){
                ivs_free(vse);
                if(vsa){
                    ivs_free(vsa);
                }
                if(vsb){
                    ivs_free(vsb);
                }
_tm_("ivs_split failed at "+k);
                continue;
            }
            tp=_gapp->typesMgr()->get(oa->getType());
            if(!tp->clone_object(oa,&ob)){
                ivs_free(vse);
                ivs_free(vsa);
                ivs_free(vsb);
_tm_("clone_object failed");
                break;
            }
            oa->setVertices(vsa);
            ob->setVertices(vsb);
            if(report){
                set_net_flag(oa,fields[tp->index()-1],_kEdgeCreated);
                set_net_flag(ob,fields[tp->index()-1],_kEdgeCreated);
            }
            added.add(&ob);
        }
    }
    return(0);
}