コード例 #1
0
// 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);	
	}
}
コード例 #2
0
// 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);
	}
}
コード例 #3
0
// 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);	
	}
}
コード例 #4
0
// 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);
	}	
}