// create new vertex list 
// new vertex has same type with old vertex.
// new edge vertex has same type with old edge, such as inner, ordinary and crease
// new face vertex has same type with old face, such as inner, (ordinary) border
// new cell vertex only has INNER type
void hs_subdiv::create_vert_list(hs_model* pmodel
								 , point_vector& vert_points
								 , point_vector& edge_points
								 , point_vector& face_points
								 , point_vector& cell_points
								 ) 
{
	point_vector_iter vert_iter;
	size_t idx = 0;
	vert_iter = vert_points.begin();
	for (; vert_iter != vert_points.end(); ++vert_iter, ++idx) {
		pmodel->add_vert(*vert_iter, phexmodel->vert_at(idx).type() );
	}
	
	idx = 0;
	vert_iter = edge_points.begin();
	for (; vert_iter != edge_points.end(); ++vert_iter, ++idx) {
		pmodel->add_vert(*vert_iter, 
			static_cast<vert_type>( phexmodel->edge_at(idx).type() ));
	}
	
	idx = 0;
	vert_iter = face_points.begin();
	for (; vert_iter != face_points.end(); ++vert_iter, ++idx) {
		pmodel->add_vert(*vert_iter,
			static_cast<vert_type>( phexmodel->face_at(idx).type() ) );
	}
	
	vert_iter = cell_points.begin();
	for (; vert_iter != cell_points.end(); ++vert_iter) {
		pmodel->add_vert(*vert_iter, INNER_VERT);
	}
	
}
Пример #2
0
/*
 * Algorithm for finding MST on a plane uses Prim's algorithm
 * to find the MST returns pairs representing indexes of the matched points
 * complexity: O(n^2 * log(n))
 */
std::vector< std::pair<lint, lint> > naive_euclidean_mst(
        const point_vector & points) {

    ldouble cost = 0;
    lint n = points.size();
    std::vector<bool> already_in_mst(n, false);
    already_in_mst[0] = true;

    std::vector< std::pair<lint, lint> > mst;

    std::priority_queue<edge> potential_edges;

    for(lint i = 1; i < n; i++)
        potential_edges.push(edge(0, i, dist(points[0], points[i])));


    while(!potential_edges.empty()) {
        edge current = potential_edges.top();
        potential_edges.pop();
        if(!already_in_mst[current.end]) {
            cost += current.cost;
            already_in_mst[current.end] = true;
            mst.push_back(std::make_pair(current.begin, current.end));
            for(lint i = 1; i < n; i++)
                if(!already_in_mst[i])
                    potential_edges.push(edge(current.end, i,
                            dist(points[current.end], points[i])));
        }

    }

    return mst;
}
Пример #3
0
  /*----------------------------------------------------------------*/
  static void ConnectedComponent(unsigned char thresh, int marker, point_vector &inside, point_vector &boundary)
  {
    // simple connected component
    while (!inside.empty())
      {
        t_offset ofs = inside.back().ofs;
        inside.pop_back();
        add_if_inside(inside, boundary, thresh, ofs + g_cols, 4, marker);
        add_if_inside(inside, boundary, thresh, ofs - g_cols, 1, marker);
        add_if_inside(inside, boundary, thresh, ofs + 1,      2, marker);
        add_if_inside(inside, boundary, thresh, ofs - 1,      8, marker);
      }

    /* sort region's boundary */
    std::sort(boundary.begin(), boundary.end());
  }
// calculate face point coordinate by iterating each face
// there are 2 classes face: 
//	1) border face, which has 1 adjacent cell;
//	2) inner face, which has 2 adjacent cells.
void hs_subdiv::calc_face_point(point_vector& face_points, point_vector& cell_points) {
	
	hs_point cent;
	face_vector_iter face_iter = phexmodel->first_face();
	for (; face_iter != phexmodel->end_face(); ++face_iter) {
		cent.zero();
		int_set_iter vert_iter = face_iter->first_vert();
		for (; vert_iter != face_iter->end_vert(); ++vert_iter) {
			cent += phexmodel->vert_at(*vert_iter).coord();
		}
		cent /= face_iter->vert_size();
		
		//if (face_iter->fst_cell() != -1 && face_iter->snd_cell() != -1) {
		if ( face_iter->type() == INNER_FACE ) {
			// inner face
			cent = cent * 0.5 + (cell_points[face_iter->fst_cell()]
				+ cell_points[face_iter->snd_cell()]) * 0.25;
		} else if ( face_iter->type() == BORDER_FACE ) { 
			// boder face
			// find a vertex in the surface 
			assert( NULL != face_iter->acis_face() ); 
			SPAposition spa_pos( cent.x(), cent.y(), cent.z() );
			const surface& csurf = face_iter->acis_face()->geometry()->equation();
			SPAposition new_spa_pos( csurf.eval_position( csurf.param(spa_pos) ) );
			cent.set_coord( new_spa_pos.x(), new_spa_pos.y(), new_spa_pos.z() );			
		}
		
		face_points.push_back(cent);	
	}
}
// calculate cell point coordinate by iterating each cell	
void hs_subdiv::calc_cell_point( point_vector& cell_points ) {
	
	hs_point cent;
	cell_vector_iter cell_iter = phexmodel->first_cell();
	for (; cell_iter != phexmodel->end_cell(); ++cell_iter) {
		cent.zero();
		int_set_iter vert_iter = cell_iter->first_vert();
		for (; vert_iter != cell_iter->end_vert(); ++ vert_iter) {
			cent += phexmodel->vert_at(*vert_iter).coord();
		}
		cent /= cell_iter->vert_size(); 
		cell_points.push_back(cent);
	}
}
// calculate edge point coordinate by iterating each edge in model
// there are 3 classes edge: 
//	1) inner edge, whose number of adjacent faces is same with adjacent cells;
//	2) crease edge, which has 2 adjacent border faces
//	3) ordinary border edge( except crease ), 
//     which has 2 adjacent border faces and other inner faces
void hs_subdiv::calc_edge_point(point_vector& edge_points, point_vector& cell_points) {	
	
	size_t idx = 0;
	hs_point cent;
	edge_vector_iter edge_iter = phexmodel->first_edge();
	for (; edge_iter != phexmodel->end_edge(); ++edge_iter, ++idx) {
		// centroid of each edge
		cent = ( phexmodel->vert_at(edge_iter->start_vert()).coord() + 
			phexmodel->vert_at(edge_iter->end_vert()).coord() ) * 0.5;
		
		if ( edge_iter->type() == INNER_EDGE ) {
			// inner edge
			hs_point avg_face_point;
			int_set_iter face_iter = edge_iter->first_face();
			for (; face_iter != edge_iter->end_face(); ++face_iter) {
				hs_point avg_cent_face;
				hs_face& f = phexmodel->face_at(*face_iter);
				int_set_iter vitr = f.first_vert();
				for (; vitr != f.end_vert(); ++vitr) {
					avg_cent_face += phexmodel->vert_at(*vitr).coord();
				}
				avg_face_point += avg_cent_face / f.vert_size();
			} 
			avg_face_point /= edge_iter->face_size();
			
			hs_point avg_cell_point;
			int_set_iter cell_iter = edge_iter->first_cell();
			for (; cell_iter != edge_iter->end_cell(); ++cell_iter) {
				avg_cell_point += cell_points[*cell_iter];
			} 
			avg_cell_point /= edge_iter->cell_size();
			
			// average of midpoint, face point and cell point
			size_t n = edge_iter->face_size();
			cent = ((n - 3) * cent + 2 * avg_face_point + avg_cell_point) / n;
			
		} else if ( edge_iter->type() == CREASE_EDGE ) {
			// crease edge
			// find a vertex in the curve which is adjacent to crease edge
			assert( NULL != edge_iter->acis_edge() );
			SPAposition spa_pos( cent.x(), cent.y(), cent.z());
			const curve& ccurv = edge_iter->acis_edge()->geometry()->equation();
			SPAposition new_spa_pos( ccurv.eval_position( ccurv.param(spa_pos) ) );
			cent.set_coord( new_spa_pos.x(), new_spa_pos.y(), new_spa_pos.z() );
			
		} else if ( edge_iter->type() == ORDINARY_EDGE ) { 
			// ordinary border edge
			// find a vertex in the surface which is adjacent to edge
			std::set< const FACE* > face_set;
			int_set_iter face_iter = edge_iter->first_face();
			for (; face_iter != edge_iter->end_face(); ++face_iter) {
				face_set.insert( phexmodel->face_at(*face_iter).acis_face() );
			}
			// ordinary edge have 2 same adjacent surface
			face_set.erase(NULL); 
			assert( 1 == face_set.size() );
			const FACE* spa_face = *(face_set.begin());
			const surface& csurf = spa_face->geometry()->equation();
			SPAposition spa_pos( cent.x(), cent.y(), cent.z() );
			SPAposition new_spa_pos( csurf.eval_position( csurf.param(spa_pos) ) );
			cent.set_coord( new_spa_pos.x(), new_spa_pos.y(), new_spa_pos.z() );	
		}
		
		edge_points.push_back(cent);	
	}
}
// calculate vertex point by iterating each vertex
// there are 4 classes vertex: 
//	1) inner vertex, 
//	2) corner point, 
//	3) point on crease 
//	4) ordinary border point on adjacent surface
void hs_subdiv::calc_vert_point(point_vector& vert_points, point_vector& cell_points) {
	
	hs_point cent;
	vert_vector_iter vert_iter = phexmodel->first_vert();
	for (; vert_iter != phexmodel->end_vert(); ++ vert_iter) {
		
		cent = vert_iter->coord();
		
		if ( vert_iter->type() == INNER_VERT ) {
			// inner point
			hs_point avg_cell_point;
			int_set_iter cell_iter = vert_iter->first_cell();
			for (; cell_iter != vert_iter->end_cell(); ++cell_iter) {
				avg_cell_point += cell_points[*cell_iter];
			}
			
			avg_cell_point /= vert_iter->cell_size();
			
			hs_point avg_face_point;
			int_set_iter face_iter = vert_iter->first_face();
			for (; face_iter != vert_iter->end_face(); ++face_iter) {
				hs_point avg_cent_face;
				hs_face& f = phexmodel->face_at(*face_iter);
				int_set_iter vitr = f.first_vert();
				for (; vitr != f.end_vert(); ++vitr) {
					avg_cent_face += phexmodel->vert_at(*vitr).coord();
				}
				avg_face_point += avg_cent_face / f.vert_size();
			}
			
			avg_face_point /= vert_iter->face_size();
			
			hs_point avg_mid_edge;
			int_set_iter edge_iter = vert_iter->first_edge();
			for (; edge_iter != vert_iter->end_edge(); ++edge_iter) {
				avg_mid_edge += (
					phexmodel->vert_at(phexmodel->edge_at(*edge_iter).start_vert()).coord() +
					phexmodel->vert_at(phexmodel->edge_at(*edge_iter).end_vert()).coord() 
					) * 0.5;
			}
			
			avg_mid_edge /= vert_iter->edge_size();
			
			cent = (cent + avg_mid_edge * 3 + avg_face_point * 3 + avg_cell_point) / 8;
			
		} else if ( vert_iter->type() == CREASE_VERT ){
			// crease vertex
			// find the crease curve of crease vertex using set
			std::set< const EDGE* > edge_set;
			int_set_iter edge_iter = vert_iter->first_edge();
			for (; edge_iter != vert_iter->end_edge(); ++edge_iter) {
				edge_set.insert( phexmodel->edge_at(*edge_iter).acis_edge() );
			}
			edge_set.erase( NULL );
			// crease vertex only have 2 same crease curve 
			// and other adjacent edge is null
			assert( 1 == edge_set.size() );
			
			SPAposition spa_pos( cent.x(), cent.y(), cent.z());
			const EDGE* spa_edge = *(edge_set.begin());
			const curve& ccurv = spa_edge->geometry()->equation();
			SPAposition new_spa_pos( ccurv.eval_position( ccurv.param(spa_pos) ) );
			cent.set_coord( new_spa_pos.x(), new_spa_pos.y(), new_spa_pos.z() );
			
		} else if ( vert_iter->type() == ORDINARY_VERT ) { 
			// ordinary vertex
			// find the unique adjacent border surface using set
			std::set< const FACE* > face_set;
			int_set_iter face_iter = vert_iter->first_face();
			for (; face_iter != vert_iter->end_face(); ++face_iter) {
				face_set.insert( phexmodel->face_at(*face_iter).acis_face() );
			}
			face_set.erase( NULL );
			assert( 1 == face_set.size() );
			const FACE* spa_face = *(face_set.begin());
			const surface& csurf = spa_face->geometry()->equation();
			SPAposition spa_pos( cent.x(), cent.y(), cent.z() );
			SPAposition new_spa_pos( csurf.eval_position( csurf.param(spa_pos) ) );
			cent.set_coord( new_spa_pos.x(), new_spa_pos.y(), new_spa_pos.z() );
		} else {
			// corner vertex
			assert( vert_iter->type() == CORNER_VERT );
		}
		
		vert_points.push_back(cent);
	}	
}