void _buildingWall( const Polygon_2& ring, const Kernel::FT& wallHeight, PolyhedralSurface& shell ) { size_t npt = ring.size() ; for ( size_t i = 0; i < npt; i++ ) { const Point_2& a = ring.vertex( i ) ; const Point_2& b = ring.vertex( ( i+1 ) % npt ) ; LineString wallRing ; wallRing.addPoint( new Point( a.x(), a.y(), Kernel::FT( 0 ) ) ); wallRing.addPoint( new Point( b.x(), b.y(), Kernel::FT( 0 ) ) ); wallRing.addPoint( new Point( b.x(), b.y(), wallHeight ) ); wallRing.addPoint( new Point( a.x(), a.y(), wallHeight ) ); wallRing.addPoint( new Point( a.x(), a.y(), Kernel::FT( 0 ) ) ); shell.addPolygon( Polygon( wallRing ) ); } }
PolyhedralSurface::PolyhedralSurface( const MarkedPolyhedron& poly ) : Surface() { for ( MarkedPolyhedron::Facet_const_iterator fit = poly.facets_begin(); fit != poly.facets_end(); ++fit ) { LineString* face = new LineString(); MarkedPolyhedron::Halfedge_around_facet_const_circulator hit = fit->facet_begin(); do { face->addPoint( hit->vertex()->point() ); ++hit; } while ( hit != fit->facet_begin() ); // close the ring face->addPoint( hit->vertex()->point() ); _polygons.push_back( new Polygon( face ) ); } }
std::auto_ptr< Geometry > building( const Polygon& g, const Kernel::FT& wallHeight, const Kernel::FT& roofSlope ) { //typedef Straight_skeleton_2::Vertex_const_handle Vertex_const_handle ; typedef Straight_skeleton_2::Halfedge_const_handle Halfedge_const_handle ; //typedef Straight_skeleton_2::Halfedge_const_iterator Halfedge_const_iterator ; typedef Straight_skeleton_2::Face_const_iterator Face_const_iterator ; // convert to CGAL polygon and generate straight skeleton Polygon_with_holes_2 polygon = g.toPolygon_with_holes_2() ; // fix orientation algorithm::makeValidOrientation( polygon ) ; boost::shared_ptr< Straight_skeleton_2 > skeleton = CGAL::create_interior_straight_skeleton_2( polygon ) ; std::auto_ptr< PolyhedralSurface > shell( new PolyhedralSurface ); // bottom part { Polygon bottom( polygon ); bottom.reverse(); algorithm::force3D( bottom ); shell->addPolygon( bottom ); } // walls { //exterior rings _buildingWall( polygon.outer_boundary(), wallHeight, *shell ) ; //interior rings for ( Polygon_with_holes_2::Hole_const_iterator it = polygon.holes_begin(); it != polygon.holes_end(); ++it ) { _buildingWall( *it, wallHeight, *shell ) ; } } // roof { for ( Face_const_iterator it = skeleton->faces_begin(); it != skeleton->faces_end(); ++it ) { LineString roofFaceRing ; Halfedge_const_handle h = it->halfedge(), done( h ) ; bool infiniteTimeFound = false ; do { infiniteTimeFound = infiniteTimeFound || h->has_infinite_time() ; Point_2 point = h->vertex()->point() ; Kernel::FT zPoint = wallHeight + h->vertex()->time() * roofSlope ; roofFaceRing.addPoint( Point( point.x(), point.y(), zPoint ) ); h = h->next() ; } while ( h != done && ! infiniteTimeFound ); if ( ! infiniteTimeFound ) { roofFaceRing.addPoint( roofFaceRing.startPoint() ); shell->addPolygon( Polygon( roofFaceRing ) ); } } } return std::auto_ptr< Geometry >( new Solid( shell.release() ) ); }