📄 ivp_compact_recursive.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
#include <ivp_physics.hxx>
#include <ivu_hash.hxx>
#include <ivp_compact_surface.hxx>
#include <ivp_compact_ledge.hxx>
#include <ivp_compact_recursive.hxx>
#include <ivp_surbuild_pointsoup.hxx>
IVP_Compact_Recursive::IVP_Compact_Recursive() : ledges(128) {
}
IVP_Compact_Recursive::~IVP_Compact_Recursive(){
}
void IVP_Compact_Recursive::add_compact_ledge(const IVP_Compact_Ledge *ledge){
ledges.add((IVP_Compact_Ledge *)ledge);
}
void IVP_Compact_Recursive::add_compact_ledge_treenode(const IVP_Compact_Ledgetree_Node *node){
if (node->is_terminal()){
add_compact_ledge(node->get_compact_ledge());
}else{
add_compact_ledge_treenode( node->left_son());
add_compact_ledge_treenode( node->right_son());
}
}
void IVP_Compact_Recursive::add_compact_surface( const IVP_Compact_Surface *surface){
add_compact_ledge_treenode( surface->get_compact_ledge_tree_root());
}
void IVP_Compact_Recursive::build_convex_hull(){
IVP_Hash point_hash( 1024, sizeof(IVP_U_Float_Point),0);
IVP_U_Vector<IVP_U_Point> points;
for (int k = ledges.len()-1; k>=0;k--){
IVP_Compact_Ledge *ledge = ledges.element_at(k);
IVP_U_Float_Point *point_array = ledge->get_point_array();
IVP_Compact_Triangle *tri = ledge->get_first_triangle();
for (int t = ledge->get_n_triangles()-1; t>=0; t--){
for (int e = 0; e<3;e++){
const IVP_Compact_Edge *edge = tri->get_edge(e);
const IVP_U_Float_Point *p = &point_array[edge->get_start_point_index()];
if ( point_hash.find( (char *)p )) continue;
point_hash.add((char *)p,(void *)p);
points.add( new IVP_U_Point(p));
}
tri = tri->get_next_tri();
}
}
hull = IVP_SurfaceBuilder_Pointsoup::convert_pointsoup_to_compact_ledge(&points);
for (int x = points.len()-1; x>=0;x--){
delete points.element_at(x);
}
}
void IVP_Compact_Recursive::set_rekursive_convex_hull(){
IVP_Hash point_hash( 1024, sizeof(IVP_U_Float_Point),(void *)-1);
int n_points_in_hash = 0;
struct Triangle_Key {
int point_index[3];
void set_tri(int a, int b, int c){
if (b<a){ int x = a;a=b;b=a;a=x; };
if (c<a){ int x = a;a=c;c=a;a=x; };
if (b<a){ int x = a;a=b;b=a;a=x; };
// now a < b < c
point_index[0] = a; point_index[1] = b; point_index[2] = c;
}
} triangle_key;
struct Edge_Key {
int point_index[2];
void set_edge(int a, int b){
if (b<a){ int x = a;a=b;b=a;a=x; };
// now a < b < c
point_index[0] = a; point_index[1] = b;
}
} edge_key;
IVP_Hash triangle_hash(1024, sizeof(Triangle_Key),0);
IVP_Hash edge_hash( 1024, sizeof(Edge_Key),0);
// set all hashes
for (int ledge_i = ledges.len()-1; ledge_i>=0; ledge_i--){
IVP_Compact_Ledge *ledge = ledges.element_at(ledge_i);
IVP_Compact_Triangle *tri = ledge->get_first_triangle();
for (int t = ledge->get_n_triangles()-1; t>=0; tri = tri->get_next_tri(),t--){
const IVP_U_Float_Point *p[3];
p[0] = tri->get_edge(0)->get_start_point( ledge );
p[1] = tri->get_edge(1)->get_start_point( ledge );
p[2] = tri->get_edge(2)->get_start_point( ledge );
int pi[3];
// convert points to unique point nums
for (int i = 0; i<3;i++){
int ind = (int)point_hash.find( (char *)p[i]);
if (ind<0){
point_hash.add( (char *)p[i], (void *)n_points_in_hash);
ind = n_points_in_hash++;
}
pi[i] = ind;
}
// add triangle to hash
triangle_key.set_tri(pi[0], pi[1], pi[2]);
if (!triangle_hash.find( (char *)&triangle_key )){
triangle_hash.add( (char *)&triangle_key, (void *)tri );
}
// add edges to hash
for (int j = 0; j<3;j++){
edge_key.set_edge( pi[j], pi[ (j+1)%3]);
if (!edge_hash.find( (char *)&edge_key)){
edge_hash.add( (char *)&edge_key, tri);
}
}
}
}
int edges_found = 0;
int edges_not_found = 0;
// set all flags
{
IVP_Compact_Ledge *ledge = hull;
IVP_Compact_Triangle *tri = ledge->get_first_triangle();
for (int t = ledge->get_n_triangles()-1; t>=0; tri = tri->get_next_tri(),t--){
const IVP_U_Float_Point *p[3];
p[0] = tri->get_edge(0)->get_start_point( ledge );
p[1] = tri->get_edge(1)->get_start_point( ledge );
p[2] = tri->get_edge(2)->get_start_point( ledge );
int pi[3];
// convert points to unique point nums
for (int i = 0; i<3;i++){
int ind = (int)point_hash.find( (char *)p[i]);
pi[i] = ind;
}
// find triangle in hash
triangle_key.set_tri(pi[0], pi[1], pi[2]);
if (!triangle_hash.find( (char *)&triangle_key )){
tri->set_is_virtual(1);
}
// find edges in hash
for (int j = 0; j<3;j++){
edge_key.set_edge( pi[j], pi[ (j+1)%3]);
if (!edge_hash.find( (char *)&edge_key)){
((IVP_Compact_Edge *)tri->get_edge(j))->set_is_virtual(1);
edges_not_found ++;
}else{
edges_found ++;
}
}
}
}
IVP_IF(1){
//printf("extra convex hull rekursive: edges not found %i found %i\n", edges_not_found, edges_found);
}
}
IVP_Compact_Ledge *IVP_Compact_Recursive::compile(){
build_convex_hull();
if (hull) set_rekursive_convex_hull();
return hull;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -