📄 ivp_compact_ledge_gen.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
/********************************************************************************
* File: ivp_compact_ledge_gen.cxx
* Description: generation of compacted ledge representation
* from intermediate (non-compact) representation.
********************************************************************************/
#include <ivp_physics.hxx>
#include <string.h>
#include <ivu_hash.hxx>
#include <ivp_object_polygon_tetra.hxx>
#include <ivp_i_point_vhash.hxx>
#include <ivp_cache_object.hxx>
#include <ivp_compact_ledge.hxx>
#include <ivp_compact_ledge_solver.hxx>
#include <ivp_compact_ledge_gen.hxx>
///////////////////////////////////////////////////////////////////////////////////////
IVP_Compact_Ledge_Generator::IVP_Compact_Ledge_Generator()
{
P_MEM_CLEAR(this);
}
int IVP_Compact_Ledge_Generator::prepare_compact_ledge(IVP_U_Vector<IVP_Triangle>*triangles)
{
this->orig_triangles = triangles; // for validate
n_triangles = triangles->len();
// some intermediate data structs
int hash_size=16;
while(hash_size < (n_triangles * 3) / 2){
hash_size = hash_size<<1; // 2^x
}
point_hash = new IVP_point_hash(hash_size);
// generate compact triangles
// generate compact triangles
// generate compact triangles
// index triangles, ATT: destroys hesse info
{
int i;
for(i=0; i<n_triangles; i++){
IVP_Triangle *tri = triangles->element_at(i);
tri->index = i;
// build up point hash and compact point hash
int j;
IVP_Tri_Edge *e = &tri->three_edges[0];
for(j=0; j<3; e = e->next, j++){
if(!point_hash->find_point(e->start_point)){
e->start_point->tmp.compact_index = point_cnt;
point_cnt++;
point_hash->add_point(e->start_point);
// make new compact point and add to vector
point_vec.add(e->start_point);
}
}
}
}
edge_cnt=0;
edge_hash = new IVP_Hash(hash_size*4, sizeof(void *), (void *)-1);
{
int i;
// fill in triangles
for(i=0; i<n_triangles; i++){
IVP_Triangle *tri = triangles->element_at(i);
IVP_Compact_Triangle *c_tri = new IVP_Compact_Triangle();
// index
c_tri->set_tri_index(tri->index);
// pierce info
if(tri->pierced_triangle){
c_tri->set_pierce_index(tri->pierced_triangle->index);
}else{
printf("no valid pierce index!? Probably a backside triangle...\n");
}
// material info
c_tri->set_material_index(0); // @@@ DUMMY
// fill in edge topologie
// fill in edge topologie
{
int j;
IVP_Tri_Edge *edge = &tri->three_edges[0];
for( j=0; j<3; edge = edge->next , j++){
IVP_Compact_Edge *c_edge = &c_tri->c_three_edges[j];
// point index already set
c_edge->set_start_point_index(edge->start_point->tmp.compact_index);
IVP_ASSERT(edge_hash->find((char *)&edge) == (void *)-1);
edge_hash->add((char *)&edge, (void *)(i * 4 + j + 1)); // for opposites
edge_cnt++;
}
}
// add triangle to vec
triangle_vec.add(c_tri);
}
}
{
int i;
// Triangle info second pass: opposites
IVP_ASSERT(n_triangles == triangle_vec.len());
for(i=0; i<n_triangles; i++){
int j;
IVP_Triangle *tri = triangles->element_at(i);
IVP_Compact_Triangle *c_tri = triangle_vec.element_at(i);
IVP_Tri_Edge *e = &tri->three_edges[0];
for(j=0; j<3; e = e->next, j++){
IVP_Compact_Edge *c_edge = &c_tri->c_three_edges[j];
IVP_Tri_Edge *opp = e->opposite;
int opp_index = (int)edge_hash->find((char *)&opp);
IVP_ASSERT(opp_index>=0);
int rel_index = opp_index - (i*4 + j + 1);
c_edge->set_opposite_index(rel_index);
}
}
}
// return calculated size of all
int size=0;
size += sizeof(IVP_Compact_Ledge);
size += sizeof(IVP_Compact_Triangle) * n_triangles;
size += sizeof(IVP_Compact_Poly_Point) * point_cnt;
return size;
}
void IVP_Compact_Ledge_Generator::generate_compact_ledge(uchar *mem)
{
// mem should be 16 aligned
// mem: - IVP_Compact_Ledge
// - Array of IVP_Compact_Triangle
// - Array of IVP_Compact_Poly_Point
// some header info
IVP_Compact_Ledge *c_ledge = (IVP_Compact_Ledge *)mem;
this->compact_ledge = c_ledge;
c_ledge->c_ledge_init();
c_ledge->n_triangles = n_triangles;
mem += sizeof(IVP_Compact_Ledge);
int i;
// copy triangle info (including edges)
IVP_ASSERT(n_triangles == triangle_vec.len());
for(i=0; i<n_triangles; i++){
memcpy(mem, triangle_vec.element_at(i), sizeof(IVP_Compact_Triangle));
mem += sizeof(IVP_Compact_Triangle);
}
// copy point info
IVP_ASSERT(point_cnt == point_vec.len());
c_ledge->set_offset_ledge_points( (int)(mem - (uchar *)c_ledge) );
for(i=0; i<point_cnt; i++){
IVP_Compact_Poly_Point *cpp = (IVP_Compact_Poly_Point *)mem;
cpp->hesse_val = 0.0f;
cpp->set( point_vec.element_at(i));
mem += sizeof(IVP_Compact_Poly_Point);
}
// copy edge common info
//c_ledge->c_common_offset = 0;
// set sizeinfo
c_ledge->set_is_compact( IVP_TRUE);
c_ledge->set_size((int)(mem - (uchar *)c_ledge));
}
#ifdef DEBUG
IVP_RETURN_TYPE IVP_Compact_Ledge_Generator::validate()
{
// checks wether the compact ledge has any similarity with the
// original version ...
IVP_ASSERT(compact_ledge->n_triangles == triangle_vec.len());
// all triangles
const IVP_Compact_Triangle *c_triangles = compact_ledge->get_first_triangle();
int i;
for(i=0; i<n_triangles; i++){
IVP_Triangle *tri = this->orig_triangles->element_at(i);
const IVP_Compact_Triangle *c_tri = &c_triangles[i];
// check tri info
IVP_ASSERT(c_tri->get_tri_index() == i);
if(tri->pierced_triangle){
IVP_ASSERT(c_tri->get_pierce_index() == tri->pierced_triangle->index);
}
IVP_ASSERT(c_tri->get_material_index() == 0);
// all tri edges
IVP_Tri_Edge *edge = &tri->three_edges[0];
int j;
for(j=0; j<3; edge=edge->next,j++){
const IVP_Compact_Edge *c_edge = &c_tri->c_three_edges[j];
int opp_index = (int)edge_hash->find((char *)&edge->opposite);
IVP_ASSERT(opp_index>=0);
int rel_index = opp_index - (i*4 + j + 1);
IVP_ASSERT(rel_index == c_edge->get_opposite_index());
const IVP_Compact_Poly_Point *c_po = IVP_CLS.give_object_coords(c_edge->get_opposite(),compact_ledge);
IVP_ASSERT(edge->opposite->start_point->quad_distance_to(c_po) < 1e-3f);
IVP_ASSERT(edge->opposite->opposite == edge);
IVP_ASSERT(c_edge->get_opposite()->get_opposite() == c_edge);
IVP_ASSERT(c_edge->get_compact_ledge() == compact_ledge);
const IVP_Compact_Poly_Point *c_point = IVP_CLS.give_object_coords(c_edge,compact_ledge);
IVP_ASSERT(edge->start_point->quad_distance_to(c_point) < 1e-3f);
c_po = IVP_CLS.give_object_coords(c_edge->get_next(),compact_ledge);
IVP_ASSERT(edge->next->start_point->quad_distance_to(c_po) < 1e-3f);
}
}
return IVP_OK;
}
#endif
IVP_Compact_Ledge_Generator::~IVP_Compact_Ledge_Generator()
{
int i;
// restore hesse info
for(i=0; i<n_triangles; i++){
IVP_Triangle *tri = orig_triangles->element_at(i);
tri->calc_hesse();
}
// delete point intermediates
point_vec.clear();
P_DELETE(point_hash);
// edge intermediates
P_DELETE(edge_hash);
// delete triangle intermediates
for(i=0; i<n_triangles; i++){
delete triangle_vec.element_at(i);
}
triangle_vec.clear();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -