2023-03-22 11:47:00 +01:00
# ifdef IFOPSH_WITH_CGAL
2020-01-26 13:12:19 +01:00
# include "../ifcgeom/kernels/cgal/CgalKernel.h"
2023-03-21 20:15:01 +01:00
# include "../ifcgeom/IfcGeomFilter.h"
# include "../ifcgeom/Iterator.h"
2020-01-26 13:12:19 +01:00
# include <CGAL/box_intersection_d.h>
# include <CGAL/minkowski_sum_3.h>
# include <CGAL/AABB_tree.h>
# include <CGAL/AABB_traits.h>
# include <CGAL/Polyhedron_3.h>
# include <CGAL/AABB_face_graph_triangle_primitive.h>
# include <fstream>
# include <iostream>
template < typename T >
T enlarge ( const T & t , double d = 1.e-5 ) {
2020-04-03 14:56:46 +00:00
typename T : : NT min [ 3 ] ;
typename T : : NT max [ 3 ] ;
2020-01-26 13:12:19 +01:00
for ( int i = 0 ; i < t . dimension ( ) ; + + i ) {
min [ i ] = t . min_coord ( i ) - d ;
max [ i ] = t . max_coord ( i ) + d ;
}
return T ( min , max , t . handle ( ) ) ;
}
template < class HDS >
struct Build_Offset : public CGAL : : Modifier_base < HDS > {
std : : list < cgal_shape_t : : Facet_handle > input ;
void operator ( ) ( HDS & hds ) {
// Postcondition: hds is a valid polyhedral surface.
CGAL : : Polyhedron_incremental_builder_3 < HDS > B ( hds ) ;
int Nv = 0 , Nf = 0 ;
for ( auto & f : input ) {
Nv + = 3 ;
Nf + = 1 ;
}
B . begin_surface ( Nv , Nf ) ;
for ( auto & f : input ) {
auto p0 = f - > facet_begin ( ) - > vertex ( ) - > point ( ) ;
auto p1 = f - > facet_begin ( ) - > next ( ) - > vertex ( ) - > point ( ) ;
auto p2 = f - > facet_begin ( ) - > next ( ) - > next ( ) - > vertex ( ) - > point ( ) ;
auto O = CGAL : : centroid ( p0 , p1 , p2 ) ;
Kernel_ : : Point_3 * p012 [ 3 ] = { & p0 , & p1 , & p2 } ;
for ( int i = 0 ; i < 3 ; + + i ) {
* p012 [ i ] = CGAL : : ORIGIN + ( ( ( * ( p012 [ i ] ) ) - CGAL : : ORIGIN ) + ( ( * ( p012 [ i ] ) ) - O ) ) ;
B . add_vertex ( * p012 [ i ] ) ;
}
}
Nv = 0 ;
for ( int i = 0 ; i < Nf ; + + i ) {
B . begin_facet ( ) ;
B . add_vertex_to_facet ( Nv + + ) ;
B . add_vertex_to_facet ( Nv + + ) ;
B . add_vertex_to_facet ( Nv + + ) ;
B . end_facet ( ) ;
}
B . end_surface ( ) ;
}
} ;
template < typename Ts >
2020-03-23 09:20:01 +01:00
std : : list < cgal_shape_t : : Facet_handle > connected_faces ( cgal_shape_t : : Facet_handle f , const Ts & excluded ) {
2020-01-26 13:12:19 +01:00
std : : set < cgal_shape_t : : Facet_handle > fs = { f } ;
std : : function < void ( cgal_shape_t : : Facet_handle & f ) > process ;
process = [ & fs , & process , & excluded ] ( cgal_shape_t : : Facet_handle & f ) {
cgal_shape_t : : Halfedge_around_facet_circulator circ = f - > facet_begin ( ) , end ( circ ) ;
do {
auto ff = circ - > opposite ( ) - > facet ( ) ;
if ( excluded . find ( ff ) = = excluded . end ( ) ) {
auto p = fs . insert ( ff ) ;
if ( p . second ) {
process ( ff ) ;
}
}
} while ( + + circ ! = end ) ;
} ;
process ( f ) ;
return std : : list < cgal_shape_t : : Facet_handle > ( fs . begin ( ) , fs . end ( ) ) ;
}
template < class HDS >
struct Builder_With_Map : public CGAL : : Modifier_base < HDS > {
std : : list < cgal_shape_t : : Facet_handle > input ;
std : : map < Kernel_ : : Point_3 , Kernel_ : : Point_3 > mapping ;
void operator ( ) ( HDS & hds ) {
// Postcondition: hds is a valid polyhedral surface.
CGAL : : Polyhedron_incremental_builder_3 < HDS > B ( hds ) ;
std : : set < Kernel_ : : Point_3 > used_points ;
for ( auto & f : input ) {
cgal_shape_t : : Halfedge_around_facet_circulator circ = f - > facet_begin ( ) , end ( circ ) ;
do {
auto P = circ - > vertex ( ) - > point ( ) ;
auto it = mapping . find ( P ) ;
if ( it = = mapping . end ( ) ) {
std : : wcout < < " WARNING unprojected point :( " < < std : : endl ;
} else {
P = it - > second ;
}
used_points . insert ( P ) ;
} while ( + + circ ! = end ) ;
}
B . begin_surface ( used_points . size ( ) , input . size ( ) ) ;
for ( auto & p : used_points ) {
B . add_vertex ( p ) ;
}
for ( auto & f : input ) {
B . begin_facet ( ) ;
cgal_shape_t : : Halfedge_around_facet_circulator circ = f - > facet_begin ( ) , end ( circ ) ;
do {
auto P = circ - > vertex ( ) - > point ( ) ;
auto it = mapping . find ( P ) ;
if ( it = = mapping . end ( ) ) {
std : : wcout < < " WARNING unprojected point :( " < < std : : endl ;
} else {
P = it - > second ;
}
auto jt = used_points . find ( P ) ;
if ( jt = = used_points . end ( ) ) {
throw std : : runtime_error ( " Unable to map point " ) ;
}
size_t idx = std : : distance ( used_points . begin ( ) , jt ) ;
std : : wcout < < " idx " < < idx < < std : : endl ;
B . add_vertex_to_facet ( idx ) ;
} while ( + + circ ! = end ) ;
B . end_facet ( ) ;
}
B . end_surface ( ) ;
}
} ;
double facet_area ( const cgal_shape_t : : Facet_handle & f ) ;
void dump_facet ( const cgal_shape_t : : Facet_handle & f ) ;
struct remove_thickness {
typedef Kernel_ : : Point_3 Point ;
typedef Kernel_ : : Plane_3 Plane ;
typedef Kernel_ : : Vector_3 Vector ;
typedef Kernel_ : : Segment_3 Segment ;
typedef Kernel_ : : Ray_3 Ray ;
typedef CGAL : : Polyhedron_3 < Kernel_ > Polyhedron ;
typedef CGAL : : AABB_face_graph_triangle_primitive < Polyhedron > Primitive ;
typedef CGAL : : AABB_traits < Kernel_ , Primitive > Traits ;
typedef CGAL : : AABB_tree < Traits > Tree ;
typedef boost : : optional < Tree : : Intersection_and_primitive_id < Ray > : : Type > Ray_intersection ;
cgal_shape_t polyhedron , polyhedron2 , flattened ;
remove_thickness ( const cgal_shape_t & p )
// edge_collapse(p) still does not work :(
: polyhedron ( p )
, polyhedron2 ( p ) {
CGAL : : Polygon_mesh_processing : : triangulate_faces ( polyhedron ) ;
CGAL : : Polygon_mesh_processing : : triangulate_faces ( polyhedron2 ) ;
2023-07-07 14:36:01 +00:00
std : : list < cgal_shape_t : : Facet_handle > non_degenerate , degenerate , longitudinal ;
2020-01-26 13:12:19 +01:00
std : : set < cgal_shape_t : : Facet_iterator > thin_sides ;
std : : wcout < < " ALL FACES: " < < std : : endl ;
for ( auto & f : faces ( polyhedron ) ) {
dump_facet ( f ) ;
if ( facet_area ( f ) > 1.e-20 ) {
non_degenerate . push_back ( f ) ;
} else {
degenerate . push_front ( f ) ;
std : : wcout < < " Degenerate, area: " < < facet_area ( f ) < < std : : endl ;
}
}
std : : wcout < < " NON DEGENERATE: " < < std : : endl ;
for ( auto & f : non_degenerate ) {
dump_facet ( f ) ;
}
cgal_shape_t enlarged_non_degenerate_triangles ;
Build_Offset < cgal_shape_t : : HDS > bo ;
bo . input = non_degenerate ;
enlarged_non_degenerate_triangles . delegate ( bo ) ;
// @todo, first on non-enlarged faces, then on enlarged; to fix projection on concave surfaces where the enlarging operation shortens projection distances.
Tree tree ( faces ( enlarged_non_degenerate_triangles ) . first , faces ( enlarged_non_degenerate_triangles ) . second , enlarged_non_degenerate_triangles ) ;
std : : map < cgal_face_descriptor_t , Kernel_ : : Vector_3 > face_normals ;
boost : : associative_property_map < std : : map < cgal_face_descriptor_t , Kernel_ : : Vector_3 > > face_normals_map ( face_normals ) ;
CGAL : : Polygon_mesh_processing : : compute_face_normals ( polyhedron , face_normals_map ) ;
for ( auto & f : non_degenerate ) {
auto O = CGAL : : centroid (
f - > facet_begin ( ) - > vertex ( ) - > point ( ) ,
f - > facet_begin ( ) - > next ( ) - > vertex ( ) - > point ( ) ,
f - > facet_begin ( ) - > next ( ) - > next ( ) - > vertex ( ) - > point ( )
) ;
Ray ray ( O , - face_normals_map [ f ] ) ;
std : : list < Ray_intersection > intersections ;
tree . all_intersections ( ray , std : : back_inserter ( intersections ) ) ;
double N = std : : numeric_limits < double > : : infinity ( ) ;
Point P ;
for ( auto & intersection : intersections ) {
if ( boost : : get < Point > ( & ( intersection - > first ) ) ) {
const Point * p = boost : : get < Point > ( & ( intersection - > first ) ) ;
const double d = std : : sqrt ( CGAL : : to_double ( ( * p - O ) . squared_length ( ) ) ) ;
if ( d > 1.e-20 & & d < N ) {
N = d ;
}
}
}
if ( N ! = std : : numeric_limits < double > : : infinity ( ) & & N > 1.e-4 ) {
thin_sides . insert ( f ) ;
}
}
std : : wcout < < " THIN SIDES: " < < std : : endl ;
for ( auto & f : thin_sides ) {
dump_facet ( f ) ;
}
for ( auto & f : non_degenerate ) {
if ( thin_sides . find ( f ) = = thin_sides . end ( ) ) {
2023-07-07 14:36:01 +00:00
longitudinal . push_back ( f ) ;
2020-01-26 13:12:19 +01:00
}
}
std : : wcout < < " LONGITUDONAL: " < < std : : endl ;
2023-07-07 14:36:01 +00:00
for ( auto & f : longitudinal ) {
2020-01-26 13:12:19 +01:00
dump_facet ( f ) ;
}
2023-07-07 14:36:01 +00:00
std : : wcout < < " faces " < < faces ( polyhedron ) . size ( ) < < " long " < < longitudinal . size ( ) < < " thin " < < thin_sides . size ( ) < < " non-degen " < < non_degenerate . size ( ) < < std : : endl ;
2020-01-26 13:12:19 +01:00
cgal_shape_t enlarged_indiv_triangles ;
Build_Offset < cgal_shape_t : : HDS > bo2 ;
2023-07-07 14:36:01 +00:00
bo2 . input = longitudinal ;
2020-01-26 13:12:19 +01:00
enlarged_indiv_triangles . delegate ( bo2 ) ;
{
std : : ofstream ofs ( " enlarged.off " ) ;
ofs . precision ( 17 ) ;
ofs < < enlarged_indiv_triangles ;
}
Tree tree2 ( faces ( enlarged_indiv_triangles ) . begin ( ) , faces ( enlarged_indiv_triangles ) . end ( ) , enlarged_indiv_triangles ) ;
std : : map < Kernel_ : : Point_3 , Kernel_ : : Point_3 > new_points ;
for ( Polyhedron : : Facet_iterator fit = polyhedron . facets_begin ( ) ;
fit ! = polyhedron . facets_end ( ) ;
+ + fit ) {
if ( CGAL : : collinear (
fit - > halfedge ( ) - > vertex ( ) - > point ( ) ,
fit - > halfedge ( ) - > next ( ) - > vertex ( ) - > point ( ) ,
fit - > halfedge ( ) - > opposite ( ) - > vertex ( ) - > point ( ) ) ) {
std : : wcout < < " degenerate triangle " < < std : : endl ;
}
}
for ( auto & v : vertices ( polyhedron ) ) {
auto O = v - > point ( ) ;
Kernel_ : : Vector_3 norm ;
Kernel_ : : Vector_3 accum ;
int count = 0 ;
CGAL : : Face_around_target_circulator < cgal_shape_t > it ( v - > halfedge ( ) , polyhedron ) , end ( it ) ;
do {
cgal_shape_t : : Facet_handle fh = ( * it ) - > halfedge ( ) - > facet ( ) ;
auto jt = std : : find ( non_degenerate . begin ( ) , non_degenerate . end ( ) , fh ) ;
std : : wcout < < " non degen: " < < ( jt ! = non_degenerate . end ( ) ) < < std : : endl ;
auto kt = std : : find ( thin_sides . begin ( ) , thin_sides . end ( ) , fh ) ;
std : : wcout < < " thin side: " < < ( kt ! = thin_sides . end ( ) ) < < std : : endl ;
if ( jt ! = non_degenerate . end ( ) & & kt = = thin_sides . end ( ) ) {
// else degenerate, prevent div by zero, do not incorporate in vnorm.
// or else part of thin side
auto p0 = ( * it ) - > facet_begin ( ) - > vertex ( ) - > point ( ) ;
auto p1 = ( * it ) - > facet_begin ( ) - > next ( ) - > vertex ( ) - > point ( ) ;
auto p2 = ( * it ) - > facet_begin ( ) - > next ( ) - > next ( ) - > vertex ( ) - > point ( ) ;
{
std : : ostringstream oss ;
oss . precision ( 8 ) ;
oss < < " p0 " < < p0 . cartesian ( 0 ) < < " " < < p0 . cartesian ( 1 ) < < " " < < p0 . cartesian ( 2 ) < < " \n " ;
oss < < " p1 " < < p1 . cartesian ( 0 ) < < " " < < p1 . cartesian ( 1 ) < < " " < < p1 . cartesian ( 2 ) < < " \n " ;
oss < < " p2 " < < p2 . cartesian ( 0 ) < < " " < < p2 . cartesian ( 1 ) < < " " < < p2 . cartesian ( 2 ) < < " \n " ;
auto osss = oss . str ( ) ;
std : : wcout < < osss . c_str ( ) < < std : : endl ;
}
auto fnorm = CGAL : : cross_product ( p0 - p1 , p2 - p1 ) ;
fnorm / = std : : sqrt ( CGAL : : to_double ( fnorm . squared_length ( ) ) ) ;
// const auto& fnorm = face_normals_map_2[*it];
std : : ostringstream oss ;
oss . precision ( 8 ) ;
oss < < fnorm . cartesian ( 0 ) < < " " < < fnorm . cartesian ( 1 ) < < " " < < fnorm . cartesian ( 2 ) ;
auto osss = oss . str ( ) ;
std : : wcout < < osss . c_str ( ) < < std : : endl ;
accum + = fnorm ;
+ + count ;
}
+ + it ;
} while ( it ! = end ) ;
norm = accum / count ;
std : : wcout < < " count " < < count < < std : : endl ;
if ( count = = 0 ) {
// part of only degenerate or only thin sides
continue ;
}
// v->vertex_begin();
Ray ray ( O , norm ) ;
std : : ostringstream oss ;
oss . precision ( 8 ) ;
oss < < O < < " -> " < < norm ;
auto osss = oss . str ( ) ;
std : : wcout < < osss . c_str ( ) < < std : : endl ;
std : : list < Ray_intersection > intersections ;
tree2 . all_intersections ( ray , std : : back_inserter ( intersections ) ) ;
double N = std : : numeric_limits < double > : : infinity ( ) ;
Point P ;
bool used_intersection = false ;
if ( intersections . size ( ) ) {
for ( auto & intersection : intersections ) {
if ( boost : : get < Point > ( & ( intersection - > first ) ) ) {
const Point * p = boost : : get < Point > ( & ( intersection - > first ) ) ;
const double d = std : : sqrt ( CGAL : : to_double ( ( * p - O ) . squared_length ( ) ) ) ;
if ( d < N & & d > 1.e-20 ) {
N = d ;
P = * p ;
std : : wcout < < " intersection @ " < < d < < std : : endl ;
}
}
}
std : : wcout < < " ----------- " < < std : : endl ;
// average the new point
new_points [ O ] = CGAL : : ORIGIN + ( ( ( O - CGAL : : ORIGIN ) + ( P - CGAL : : ORIGIN ) ) ) / 2 ;
used_intersection = true ;
}
if ( ! used_intersection ) {
std : : wcout < < " no intersection :( " < < std : : endl ;
}
}
auto thin_sides_degenerate = thin_sides ;
thin_sides_degenerate . insert ( degenerate . begin ( ) , degenerate . end ( ) ) ;
// @todo choose connected / connected_opposing based on largest combined area of facets?
2023-07-07 14:36:01 +00:00
if ( longitudinal . size ( ) = = 0 ) {
std : : wcout < < " no longitudinal faces detected :( " < < std : : endl ;
2020-01-26 17:11:14 +01:00
return ;
}
2023-07-07 14:36:01 +00:00
auto connected = connected_faces ( * longitudinal . begin ( ) , thin_sides_degenerate ) ;
2020-01-26 13:12:19 +01:00
decltype ( connected ) connected_opposing ;
2023-07-07 14:36:01 +00:00
for ( auto & f : longitudinal ) {
2020-01-26 13:12:19 +01:00
if ( std : : find ( connected . begin ( ) , connected . end ( ) , f ) = = connected . end ( ) ) {
connected_opposing = connected_faces ( f , thin_sides_degenerate ) ;
2023-07-07 14:36:01 +00:00
std : : set < cgal_shape_t : : Facet_handle > longi ( longitudinal . begin ( ) , longitudinal . end ( ) ) ;
2020-01-26 13:12:19 +01:00
std : : set < cgal_shape_t : : Facet_handle > both_sides ( connected . begin ( ) , connected . end ( ) ) ;
both_sides . insert ( connected_opposing . begin ( ) , connected_opposing . end ( ) ) ;
if ( longi = = both_sides ) {
std : : wcout < < " Facet connection functioning properly " < < std : : endl ;
} else {
std : : wcout < < " Facet connection functioning incorrectly " < < std : : endl ;
}
break ;
}
}
Builder_With_Map < cgal_shape_t : : HDS > b2 ;
b2 . input = connected ;
b2 . mapping = new_points ;
flattened . delegate ( b2 ) ;
}
} ;
struct intersection_validator {
2023-03-21 20:15:01 +01:00
typedef std : : list < std : : pair < const IfcUtil : : IfcBaseEntity * , CGAL : : Nef_polyhedron_3 < Kernel_ > > > nefs_t ;
2020-01-26 13:12:19 +01:00
typedef CGAL : : Box_intersection_d : : Box_with_handle_d < double , 3 , nefs_t : : value_type * > Box ;
std : : vector < Box > boxes ;
nefs_t nefs ;
2020-01-29 14:57:49 +01:00
double total_map_time = 0. ;
double total_geom_time = 0. ;
double total_nef_time = 0. ;
double total_minkowsky_time = 0. ;
double total_box_time = 0. ;
2023-07-07 14:36:01 +00:00
std : : set < const IfcUtil : : IfcBaseEntity * > successfully_processed ;
2020-01-29 14:57:49 +01:00
intersection_validator ( IfcParse : : IfcFile & f , std : : initializer_list < std : : string > entities , double eps , bool no_progress , bool quiet , bool stderr_progress ) {
2020-01-26 13:12:19 +01:00
2023-11-15 10:32:20 +01:00
ifcopenshell : : geometry : : Settings settings ;
settings . get < ifcopenshell : : geometry : : settings : : UseWorldCoords > ( ) . value = false ;
settings . get < ifcopenshell : : geometry : : settings : : WeldVertices > ( ) . value = false ;
settings . get < ifcopenshell : : geometry : : settings : : ReorientShells > ( ) . value = true ;
settings . get < ifcopenshell : : geometry : : settings : : ConvertBackUnits > ( ) . value = true ;
settings . get < ifcopenshell : : geometry : : settings : : IteratorOutput > ( ) . value = ifcopenshell : : geometry : : settings : : NATIVE ;
settings . get < ifcopenshell : : geometry : : settings : : DisableOpeningSubtractions > ( ) . value = true ;
2020-01-26 13:12:19 +01:00
std : : vector < ifcopenshell : : geometry : : filter_t > spaces_and_walls = {
IfcGeom : : entity_filter ( true , false , entities )
} ;
2023-03-21 20:15:01 +01:00
IfcGeom : : Iterator context_iterator ( " cgal " , settings , & f , spaces_and_walls , 1 ) ;
2020-01-26 13:12:19 +01:00
if ( ! context_iterator . initialize ( ) ) {
return ;
}
2020-03-23 09:20:01 +01:00
auto polycube = ifcopenshell : : geometry : : utils : : create_cube ( eps ) ;
auto cube = ifcopenshell : : geometry : : utils : : create_nef_polyhedron ( polycube ) ;
2020-01-26 13:12:19 +01:00
size_t num_created = 0 ;
int old_progress = quiet ? 0 : - 1 ;
for ( ; ; + + num_created ) {
bool has_more = true ;
if ( num_created ) {
has_more = context_iterator . next ( ) ;
}
2023-03-21 20:15:01 +01:00
IfcGeom : : BRepElement * geom_object = nullptr ;
2020-01-26 13:12:19 +01:00
if ( has_more ) {
geom_object = context_iterator . get_native ( ) ;
}
if ( ! geom_object ) {
break ;
}
std : : stringstream ss ;
2024-08-23 20:29:07 +02:00
geom_object - > product ( ) - > toString ( ss ) ;
2020-01-26 13:12:19 +01:00
auto sss = ss . str ( ) ;
std : : wcout < < sss . c_str ( ) < < std : : endl ;
for ( auto & g : geom_object - > geometry ( ) ) {
2023-11-02 09:04:34 +01:00
cgal_shape_t s = * std : : static_pointer_cast < ifcopenshell : : geometry : : CgalShape > ( g . Shape ( ) ) ;
2023-07-27 16:42:06 +08:00
const auto & m = g . Placement ( ) - > ccomponents ( ) ;
const auto & n = geom_object - > transformation ( ) . data ( ) - > ccomponents ( ) ;
2020-01-26 13:12:19 +01:00
const cgal_placement_t trsf (
m ( 0 , 0 ) , m ( 0 , 1 ) , m ( 0 , 2 ) , m ( 0 , 3 ) ,
m ( 1 , 0 ) , m ( 1 , 1 ) , m ( 1 , 2 ) , m ( 1 , 3 ) ,
m ( 2 , 0 ) , m ( 2 , 1 ) , m ( 2 , 2 ) , m ( 2 , 3 ) ) ;
const cgal_placement_t trsf2 (
n ( 0 , 0 ) , n ( 0 , 1 ) , n ( 0 , 2 ) , n ( 0 , 3 ) ,
n ( 1 , 0 ) , n ( 1 , 1 ) , n ( 1 , 2 ) , n ( 1 , 3 ) ,
n ( 2 , 0 ) , n ( 2 , 1 ) , n ( 2 , 2 ) , n ( 2 , 3 ) ) ;
// Apply transformation
for ( auto & vertex : vertices ( s ) ) {
vertex - > point ( ) = vertex - > point ( ) . transform ( trsf ) . transform ( trsf2 ) ;
}
2020-01-29 14:57:49 +01:00
std : : clock_t nef_begin = std : : clock ( ) ;
2020-01-26 13:12:19 +01:00
CGAL : : Nef_polyhedron_3 < Kernel_ > nef = ifcopenshell : : geometry : : utils : : create_nef_polyhedron ( s ) ;
2020-01-29 14:57:49 +01:00
std : : clock_t nef_end = std : : clock ( ) ;
total_nef_time + = ( nef_end - nef_begin ) / ( double ) CLOCKS_PER_SEC ;
2020-01-26 13:58:02 +01:00
if ( nef . is_empty ( ) ) {
std : : wcout < < " Failed to create nef " < < std : : endl ;
continue ;
}
2023-07-07 14:36:01 +00:00
successfully_processed . insert ( geom_object - > product ( ) ) ;
2020-01-29 14:57:49 +01:00
2020-01-26 13:12:19 +01:00
nef = CGAL : : minkowski_sum_3 ( nef , cube ) ;
2020-01-29 14:57:49 +01:00
std : : clock_t minkowski_end = std : : clock ( ) ;
total_minkowsky_time + = ( minkowski_end - nef_end ) / ( double ) CLOCKS_PER_SEC ;
2020-01-26 13:12:19 +01:00
std : : wcout < < " product: " < < geom_object - > product ( ) < < std : : endl ;
nefs . push_back ( { geom_object - > product ( ) , nef } ) ;
Box b ( & * ( nefs . rbegin ( ) ) ) ;
// id_map[b.id()] = ;
for ( auto & vertex : vertices ( s ) ) {
double p [ 3 ] = {
CGAL : : to_double ( vertex - > point ( ) . cartesian ( 0 ) ) ,
CGAL : : to_double ( vertex - > point ( ) . cartesian ( 1 ) ) ,
CGAL : : to_double ( vertex - > point ( ) . cartesian ( 2 ) )
} ;
b . extend ( p ) ;
}
boxes . push_back ( enlarge ( b ) ) ;
/*
std::ostringstream ss;
ss << geom_object->product()->data().toString() << std::endl << b.min_coord(0) << " - " << b.max_coord(0) << std::endl;
auto sss = ss.str();
std::wcout << sss.c_str();
*/
}
if ( ! no_progress ) {
if ( quiet ) {
const int progress = context_iterator . progress ( ) ;
for ( ; old_progress < progress ; + + old_progress ) {
std : : cout < < " . " ;
if ( stderr_progress )
std : : cerr < < " . " ;
}
std : : cout < < std : : flush ;
if ( stderr_progress )
std : : cerr < < std : : flush ;
} else {
const int progress = context_iterator . progress ( ) / 2 ;
if ( old_progress ! = progress ) Logger : : ProgressBar ( progress ) ;
old_progress = progress ;
}
}
}
if ( ! no_progress & & quiet ) {
for ( ; old_progress < 100 ; + + old_progress ) {
std : : cout < < " . " ;
if ( stderr_progress )
std : : cerr < < " . " ;
}
std : : cout < < std : : flush ;
if ( stderr_progress )
std : : cerr < < std : : flush ;
} else {
Logger : : Status ( " \r Done fixing space boundaries for " + boost : : lexical_cast < std : : string > ( num_created ) +
" objects " ) ;
}
2023-03-21 20:15:01 +01:00
/*
// @todo
2020-01-29 14:57:49 +01:00
total_geom_time = context_iterator.converter().total_geom_time;
total_map_time = context_iterator.converter().total_map_time;
2023-03-21 20:15:01 +01:00
*/
2020-01-26 13:12:19 +01:00
}
template < typename Fn >
void operator ( ) ( Fn fn ) {
2020-01-29 14:57:49 +01:00
std : : clock_t box_overlap_begin = std : : clock ( ) ;
2020-04-03 16:24:07 +02:00
CGAL : : box_self_intersection_d ( boxes . begin ( ) , boxes . end ( ) , [ ] ( Box & x , Box & y ) { } ) ;
2020-01-29 14:57:49 +01:00
std : : clock_t box_overlap_end = std : : clock ( ) ;
total_box_time + = ( box_overlap_end - box_overlap_begin ) / ( double ) CLOCKS_PER_SEC ;
2020-01-26 13:12:19 +01:00
CGAL : : box_self_intersection_d ( boxes . begin ( ) , boxes . end ( ) , fn ) ;
}
} ;
2023-03-22 11:47:00 +01:00
# endif