Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] Re: Sequence of boolops on general polygons

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] Re: Sequence of boolops on general polygons


Chronological Thread 
  • From: Shriramana Sharma <>
  • To:
  • Subject: Re: [cgal-discuss] Re: Sequence of boolops on general polygons
  • Date: Tue, 12 Feb 2013 13:36:29 +0530

On Mon, Feb 11, 2013 at 8:28 PM, Efi Fogel
<>
wrote:
> Thank you for the patch. I have applied it.
> The changes will be included in the next release.

Hello Efi and thank you and Ophir very much for all your replies.
Here's a further improved version of the same -- I added output of
bezier contents. (The print_utils.h provided only handles simple
polygons.)

--
Shriramana Sharma
/*! \file bezier_traits_adapter.cpp
 * Using the traits adaptor to generate a traits class for Bezier polygons.
 */

#include <CGAL/basic.h>

#ifndef CGAL_USE_CORE
#include <iostream>
int main ()
{
  std::cout << "Sorry, this example needs CORE ..." << std::endl;
  return (0);
}
#else

#include <CGAL/Cartesian.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <CGAL/Arr_Bezier_curve_traits_2.h>
#include <CGAL/Gps_traits_2.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/General_polygon_set_2.h>
#include <CGAL/Timer.h>

#include <fstream>

typedef CGAL::CORE_algebraic_number_traits              Nt_traits;
typedef Nt_traits::Rational                             Rational;
typedef Nt_traits::Algebraic                            Algebraic;

typedef CGAL::Cartesian<Rational>                       Rat_kernel;
typedef CGAL::Cartesian<Algebraic>                      Alg_kernel;
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
                                                        Traits_2;
  
typedef Rat_kernel::Point_2                             Bezier_rat_point;
typedef Traits_2::Curve_2                               Bezier_curve;
typedef Traits_2::X_monotone_curve_2                    Bezier_X_monotone_curve;
typedef CGAL::Gps_traits_2<Traits_2>                    Bezier_traits;
typedef Bezier_traits::General_polygon_2                Bezier_polygon;
typedef Bezier_traits::General_polygon_with_holes_2     Bezier_polygon_with_holes;
typedef CGAL::General_polygon_set_2<Bezier_traits>      Bezier_polygon_set;
typedef std::vector<Bezier_polygon>                     Bezier_polygon_vector;

Bezier_curve read_bezier_curve ( std::istream& is, bool aDoubleFormat )
{
  // Read the number of control points.
  unsigned int  n;

  is >> n;
  
  // Read the control points.
  std::vector<Bezier_rat_point> ctrl_pts;
  
  for ( unsigned int k = 0; k < n; k++)
  {
    Bezier_rat_point p ;
    if ( aDoubleFormat )
    {
      double x,y ;
      is >> x >> y ;
      p = Bezier_rat_point(x,y);
    }
    else
    {
      is >> p ;
    }
    
    if ( k == 0 || ctrl_pts[k-1] != p ) 
    {
      ctrl_pts.push_back(p) ;
    }
  }

  return Bezier_curve(ctrl_pts.begin(),ctrl_pts.end());
}

bool read_bezier ( char const* aFileName, Bezier_polygon_set& rSet )
{
  
  bool rOK = false ;
  
  std::ifstream in_file (aFileName);
  
  if ( in_file )
  {
    try
    {
      std::cout << "Reading " << aFileName << std::endl ;
          
      std::string format ;
      std::getline(in_file,format);
      
      bool lDoubleFormat = ( format.length() >= 6 &&
                             format.substr(0,6) == "DOUBLE") ;
                              
      // Red the number of bezier polygon with holes
      unsigned int n_regions ;
      in_file >> n_regions;
      
      for ( unsigned int r = 0 ; r < n_regions ; ++ r )
      {
        Bezier_polygon_vector  polygons ;
        
        // Read the number of bezier curves.
        unsigned int n_boundaries;
        in_file >> n_boundaries;
      
        for ( unsigned int b = 0 ; b < n_boundaries ; ++ b )
        {
          // Read the number of bezier curves.
          unsigned int n_curves;
          in_file >> n_curves;
          
          // Read the curves one by one, and construct the general polygon these
          // curve form (the outer boundary and the holes inside it).
          
          std::list<Bezier_X_monotone_curve> xcvs;
        
          for ( unsigned int k = 0; k < n_curves; ++ k ) 
          {
            // Read the current curve and subdivide it into x-monotone subcurves.
            
            std::list<CGAL::Object>                 x_objs;
            std::list<CGAL::Object>::const_iterator xoit;
            Bezier_X_monotone_curve                 xcv;
            Bezier_traits                           traits;
            Bezier_traits::Make_x_monotone_2        make_x_monotone =
              traits.make_x_monotone_2_object();
        
            Bezier_curve B = read_bezier_curve(in_file, lDoubleFormat);
            if ( B.number_of_control_points() >= 2 )
            {
                
              make_x_monotone (B, std::back_inserter (x_objs));
              
              for (xoit = x_objs.begin(); xoit != x_objs.end(); ++xoit) 
              {
                if (CGAL::assign (xcv, *xoit))
                {
                  xcvs.push_back (xcv);
                }  
              }
            }
          }  
            
          Bezier_polygon  pgn (xcvs.begin(), xcvs.end());
          
          CGAL::Orientation  orient = pgn.orientation();
          std::cout << "  Orientation: " << orient << std::endl  ;
            
          if (( b == 0 && orient == CGAL::CLOCKWISE) ||
              ( b > 0 && orient == CGAL::COUNTERCLOCKWISE))
          {
            std::cout << "    Reversing orientation: " << std::endl  ;
            pgn.reverse_orientation();
          }
            
          polygons.push_back (pgn);
        }
      
        if ( polygons.size() > 0 )
        {
          Bezier_polygon_with_holes pwh(polygons.front());
          
          if ( polygons.size() > 1 )
          {
            Bezier_polygon_vector::const_iterator it;
            for ( it = CGAL::cpp0x::next(polygons.begin()); it != polygons.end();
                  ++ it )
              pwh.add_hole(*it);    
          }
          
          if ( is_valid_polygon_with_holes(pwh, rSet.traits() ) )
          {
            std::cout << "  Successfully read bezier polygon with holes totally comprising "
                      << polygons.size() << " boundaries."
                      << std::endl ;
            rSet.join(pwh) ;      
            std::cout << "    Done." << std::endl ;
          }
          else
          {
            std::cout << "  **** Bezier polygon with holes is NOT VALID ****"
                      << std::endl ;
          }
        }
        
        rOK = true ;
      }
    }
    catch( std::exception const& x )
    {
      std::cout << "Exception ocurred during reading of bezier polygon set:"
                << x.what() << std::endl ;
    } 
    catch(...)
    {
      std::cout << "Exception ocurred during reading of bezier polygon set."
                << std::endl ;
    } 
  }
  
  return rOK ;
}

template <typename Iter>
void print_double_points ( Iter begin, Iter end )
{
	for ( Iter it = begin ; it != end ; ++ it )
		std::cout << "(" << it->x().doubleValue() << "," << it->y().doubleValue() << ")," ;
}

void print_bezier_polygon(const Bezier_polygon & b)
{
   unsigned int k=1;
   std::vector<Bezier_rat_point> subcurveCtrlPts;
   for (Bezier_polygon::Curve_const_iterator it = b.curves_begin() ; it != b.curves_end() ; ++it, ++k ) // it points to each monotone bezier forming the polygon
   {
	  const Bezier_curve * supportCurvePtr = & (it->supporting_curve()) ;
	  subcurveCtrlPts . clear () ;

	  std::cout << "Segment " << k << " from " << it->source() << " to " << it->target() << " defined by the supporting curve " ;
	  print_double_points(supportCurvePtr->control_points_begin(), supportCurvePtr->control_points_end());
	  std::cout << " in the approx parameter range ("
	            << it->parameter_range().first << "," << it->parameter_range().second << ")" << std::endl ;

	  std::cout << std::endl ;
   }
}

// The main program.
int main (int argc, char* argv[])
{
  const char* filename1 = (argc > 1) ? argv[1] : "char_g.bps";
  const char* filename2 = (argc > 2) ? argv[2] : "char_m.bps";
  const char* bop       = (argc > 3) ? argv[3] : "i";

  // Read the general polygons from the input files.
  CGAL::Timer           timer;
  Bezier_polygon_set S, S2 ;

  timer.start();
  

  if (! read_bezier (filename1, S)) {
    std::cerr << "Failed to read " << filename1 << " ..." << std::endl;
    return 1;
  }

  if (! read_bezier (filename2, S2)) {
    std::cerr << "Failed to read " << filename2 << " ..." << std::endl;
    return 1;
  }

  timer.stop();
  std::cout << "Constructed the input polygons in " << timer.time() 
            << " seconds." << std::endl << std::endl;
  
  std::cout << "Starting boolean operation..." << std::endl ;
  timer.reset();
  timer.start();
  try
  {
    switch ( bop[0] )
    {
      case 'i': S.intersection(S2); break ;
      case 'u': S.join        (S2); break ;
    }
  }
  catch( std::exception const& x )
  {
    std::cout << "An exception occurred during the boolean operation:" << x.what()
              << std::endl ;
  } 
  catch(...)
  { 
    std::cout << "An exception occurred during the boolean operation." << std::endl;
  } 
  timer.stop();
  
  std::cout << "The " << ( bop[0] == 'i' ? "intersection" : "union" ) << " computation took "
            << timer.time() << " seconds." << std::endl;

  std::list<Bezier_polygon_with_holes> pwh ;
  std::list<Bezier_polygon_with_holes>::const_iterator pwhit;
  Bezier_polygon_with_holes::Hole_const_iterator hit;

  std::cout << "The result contains " << S.number_of_polygons_with_holes()
            << " components:" << std::endl;

  unsigned int polynum, holenum;
  S.polygons_with_holes (std::back_inserter (pwh));
  for (pwhit = pwh.begin(), polynum = 1; pwhit != pwh.end(); ++pwhit, ++polynum)
  {
    std::cout << "Polygon #" << polynum << " " ;
    if (!pwhit -> is_unbounded())
    {
      std::cout << "{ Outer boundary = " << std::endl;
      print_bezier_polygon(pwhit->outer_boundary());
    }
    else std::cout << "{ No outer boundary." << std::endl;

    std::cout << "  " << pwhit->number_of_holes() << " holes" << std::endl;
    for (hit = pwhit->holes_begin(), holenum = 1; hit != pwhit->holes_end(); ++hit, ++holenum)
	{
      std::cout << "    Hole #" << holenum << " = ";
      print_bezier_polygon (*hit);
    }
  std::cout << " }" << std::endl << std::endl;
  }
  return 0;
}

#endif



Archive powered by MHonArc 2.6.18.

Top of Page