예제 #1
0
// comments relate to Sugihara-Iri paper
// this is roughly "algorithm A" from the paper, page 15/50
void VoronoiDiagram::addVertexSite(const Point& p) {
    // only add vertices within the far_radius circle
    assert( p.xyNorm() < far_radius );
    
    // 1) find the closest face and associated generator
    gen_count++;
    HEFace closest_face = fgrid->grid_find_closest_face( p );
    
    // 2) among the vertices on the closest_face
    //    find the seed, which has the lowest detH
    HEVertex v_seed = findSeedVertex(closest_face, p);
    g[v_seed].type = IN;
    VertexVector v0;
    v0.push_back(v_seed); 
    
    // 3) augment the vertex set to be deleted
    //    vertex set must remain a tree
    //    must not delete cycles
    augment_vertex_set_M(v0, p); 
    
    // 4) add new vertices on all edges that connect v0 IN edges to OUT edges
    add_new_voronoi_vertices(v0, p);
    
    // 5) generate new edges that form a loop around the region to be deleted
    HEFace newface = split_faces(p);
    
    // 6) fix the next-pointers in newface, then remove set v0
    remove_vertex_set(v0, newface);
    
    // 7) reset IN/OUT/UNDECIDED for verts, and INCIDENT/NONINCIDENT for faces
    reset_labels();

    assert( vdChecker.isValid(this) );
}
예제 #2
0
파일: bottess.c 프로젝트: kanzure/brlcad
union tree *
evaluate(union tree *tr, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
{
    RT_CK_TREE(tr);

    switch (tr->tr_op) {
	case OP_NOP:
	    return tr;
	case OP_NMG_TESS:
	    /* ugh, keep it as nmg_tess and just shove the rt_bot_internal ptr
	     * in as nmgregion. :/ Also, only doing the first shell of the first
	     * model. Primitives should only provide a single shell, right? */
	    {
		struct rt_db_internal ip;
		struct nmgregion *nmgr = BU_LIST_FIRST(nmgregion, &tr->tr_d.td_r->m_p->r_hd);
		/* the bot temporary format may be unnecessary if we can walk
		 * the nmg shells and generate soup from them directly. */
		struct rt_bot_internal *bot = nmg_bot(BU_LIST_FIRST(shell, &nmgr->s_hd), tol);

		/* causes a crash.
		   nmg_kr(nmgr);
		   free(nmgr);
		*/

		tr->tr_d.td_r->m_p = (struct model *)bot2soup(bot, tol);
		SOUP_CKMAG((struct soup_s *)tr->tr_d.td_r->m_p);

		/* fill in a db_internal with our new bot so we can free it */
		RT_DB_INTERNAL_INIT(&ip);
		ip.idb_major_type = DB5_MAJORTYPE_BRLCAD;
		ip.idb_minor_type = ID_BOT;
		ip.idb_meth = &OBJ[ID_BOT];
		ip.idb_ptr = bot;
		ip.idb_meth->ft_ifree(&ip);
	    }
	    return tr;
	case OP_UNION:
	case OP_INTERSECT:
	case OP_SUBTRACT:
	    RT_CK_TREE(tr->tr_b.tb_left);
	    RT_CK_TREE(tr->tr_b.tb_right);
	    tr->tr_b.tb_left = evaluate(tr->tr_b.tb_left, ttol, tol);
	    tr->tr_b.tb_right = evaluate(tr->tr_b.tb_right, ttol, tol);
	    RT_CK_TREE(tr->tr_b.tb_left);
	    RT_CK_TREE(tr->tr_b.tb_right);
	    SOUP_CKMAG(tr->tr_b.tb_left->tr_d.td_r->m_p);
	    SOUP_CKMAG(tr->tr_b.tb_right->tr_d.td_r->m_p);
	    split_faces(tr->tr_b.tb_left, tr->tr_b.tb_right, tol);
	    RT_CK_TREE(tr->tr_b.tb_left);
	    RT_CK_TREE(tr->tr_b.tb_right);
	    SOUP_CKMAG(tr->tr_b.tb_left->tr_d.td_r->m_p);
	    SOUP_CKMAG(tr->tr_b.tb_right->tr_d.td_r->m_p);
	    break;
	default:
	    bu_bomb("bottess evaluate(): bad op (first pass)\n");
    }

    switch (tr->tr_op) {
	case OP_UNION:
	    return compose(tr->tr_b.tb_left, tr->tr_b.tb_right, OUTSIDE, SAME, OUTSIDE);
	case OP_INTERSECT:
	    return compose(tr->tr_b.tb_left, tr->tr_b.tb_right, INSIDE, SAME, INSIDE);
	case OP_SUBTRACT:
	    return invert(compose(tr->tr_b.tb_left, invert(tr->tr_b.tb_right), OUTSIDE, OPPOSITE, INSIDE));
	default:
	    bu_bomb("bottess evaluate(): bad op (second pass, CSG)\n");
    }
    bu_bomb("Got somewhere I shouldn't have\n");
    return NULL;
}