Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] bugs in Arrangement_2 (was Arrangement_with_history_2: precondition failure and patches)

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] bugs in Arrangement_2 (was Arrangement_with_history_2: precondition failure and patches)


Chronological Thread 
  • From: David Keller <>
  • To:
  • Subject: Re: [cgal-discuss] bugs in Arrangement_2 (was Arrangement_with_history_2: precondition failure and patches)
  • Date: Sun, 06 Apr 2008 21:55:31 +0200

Hi Efi,

Thanks for the fast response.
I've quickly looked at the patch and it seems correct. I guess one can provide a more efficient implementation using the same idea of comparing the y-coordinate of a point in one curve and a segment in the other, but advancing in both curves in parallel in a controlled manner.
I agree, and I would for sure like to see your proposal being implemented in a future release.

We saw your posting from last week regarding the IO problem in the Arrangement_2 package. We are looking into it, and we'll try to give you a detailed answer soon.
I've for myself tried to get a foot on the ground on these issues: Attached is a patch (arr_io.patch) containing my fixes and a test-case derived from io.cpp in the examples-directory. As you may see from the patch I changed several files. Hence, I would appreciate if you would like to check if the changes don't break with other code in CGAL. The test-case checks on a double read-write-cycle if the number of entities in an arrangement is the same after write-reading it. It actually does not check for equal topology.

The fixes break with the current file format used for an arrangement in CGAL. Meaning, it is no longer possible to read existing CGAL-arrangement-files. However, I doubt this is an issue since the IO of arrangements has been incomplete until now.

I already asked for this on the list: Did you ever consider to use a serialization framework like Boost.Serialization in CGAL? As you may see from my changes to CGAL/IO/Arr_text_formatter.h the low level stream functionality currently used is error prone and cumbersome to debug. Moreover, you would immediately profit from a bunch of features like automatic tracking and reconstruction of pointers, non breaking file-formats through versioning etc. which are not yet realized in CGAL.

Kind regards
David Keller

diff -Naur CGAL-3.3.1.orig/include/CGAL/Arr_accessor.h CGAL-3.3.1/include/CGAL/Arr_accessor.h
--- CGAL-3.3.1.orig/include/CGAL/Arr_accessor.h	2007-08-25 21:01:33.000000000 +0200
+++ CGAL-3.3.1/include/CGAL/Arr_accessor.h	2008-04-06 17:34:08.000000000 +0200
@@ -1119,6 +1119,46 @@
   {
     return (p_arr->dcel.new_isolated_vertex());
   }
+
+  /*!
+   * Set the bottom right vertex
+   */
+  void set_bottom_right_fictitious_vertex( Dcel_vertex* vertex )
+  {
+    p_arr->v_br = vertex;
+  }
+
+  /*!
+   * Set the top right vertex
+   */
+  void set_top_right_fictitious_vertex( Dcel_vertex* vertex )
+  {
+    p_arr->v_tr = vertex;
+  }
+
+  /*!
+   * Set the bottom left vertex
+   */
+  void set_bottom_left_fictitious_vertex( Dcel_vertex* vertex )
+  {
+    p_arr->v_bl = vertex;
+  }
+
+  /*!
+   * Set the top left vertex
+   */
+  void set_top_left_fictitious_vertex( Dcel_vertex* vertex )
+  {
+    p_arr->v_tl = vertex;
+  }
+
+  /*! Set the fictitious face of the arrangement. */
+  void set_fictitious_face( Dcel_face* face )
+  {
+    p_arr->un_face = face;
+  }
+
+
   //@}
 };
 
diff -Naur CGAL-3.3.1.orig/include/CGAL/IO/Arrangement_2_reader.h CGAL-3.3.1/include/CGAL/IO/Arrangement_2_reader.h
--- CGAL-3.3.1.orig/include/CGAL/IO/Arrangement_2_reader.h	2007-08-25 21:01:33.000000000 +0200
+++ CGAL-3.3.1/include/CGAL/IO/Arrangement_2_reader.h	2008-04-06 21:05:15.000000000 +0200
@@ -123,6 +123,10 @@
                                                  MINUS_INFINITY);
     v_tr =  m_arr_access.new_vertex_at_infinity (PLUS_INFINITY,
                                                  PLUS_INFINITY);
+    m_arr_access.set_bottom_left_fictitious_vertex( v_bl );
+    m_arr_access.set_top_left_fictitious_vertex( v_tl );
+    m_arr_access.set_bottom_right_fictitious_vertex( v_br );
+    m_arr_access.set_top_right_fictitious_vertex( v_tr );
 
     // Read the DCEL vertices and store them in the vertices vector.
     formatter.read_vertices_begin();
@@ -276,6 +280,10 @@
   void _read_face(Formatter& formatter)
   {
     formatter.read_face_begin();
+  
+    // Read unbounded
+    bool ubd = formatter.read_size ("unbounded" );
+
 
     // Try reading the outer CCB of the face.
     formatter.read_outer_ccb_begin();
@@ -288,6 +296,7 @@
       // Allocate the fictitious DCEL face.
       new_f = m_arr_access.new_face();
       new_f->set_halfedge (NULL);
+      m_arr_access.set_fictitious_face( new_f );
     }
     else
     {
@@ -296,6 +305,7 @@
       he = _read_ccb (formatter, new_f, outer_size, NULL);
       new_f->set_halfedge (he);
     }
+    new_f->set_unbounded( ubd );
     formatter.read_outer_ccb_end();
 
     // Read the holes inside the face.
diff -Naur CGAL-3.3.1.orig/include/CGAL/IO/Arrangement_2_writer.h CGAL-3.3.1/include/CGAL/IO/Arrangement_2_writer.h
--- CGAL-3.3.1.orig/include/CGAL/IO/Arrangement_2_writer.h	2007-08-25 21:01:33.000000000 +0200
+++ CGAL-3.3.1/include/CGAL/IO/Arrangement_2_writer.h	2008-04-06 21:02:45.000000000 +0200
@@ -219,6 +219,9 @@
 
     formatter.write_face_begin();
 
+    // Write unbounded
+    formatter.write_size ("unbounded", static_cast<int>( f->is_unbounded() ) );
+
     // Write the outer CCB.
     formatter.write_outer_ccb_begin();
     if (f->is_fictitious())
diff -Naur CGAL-3.3.1.orig/include/CGAL/IO/Arr_text_formatter.h CGAL-3.3.1/include/CGAL/IO/Arr_text_formatter.h
--- CGAL-3.3.1.orig/include/CGAL/IO/Arr_text_formatter.h	2007-08-25 21:01:33.000000000 +0200
+++ CGAL-3.3.1/include/CGAL/IO/Arr_text_formatter.h	2008-04-06 20:59:36.000000000 +0200
@@ -27,6 +27,7 @@
 
 #include <CGAL/basic.h>
 #include <iostream>
+#include <string>
 
 CGAL_BEGIN_NAMESPACE
 
@@ -391,6 +392,10 @@
     int  val;
 
     in() >> val;
+
+    // ignore blank after value
+    m_in->ignore();
+
     return (val);
   }
 
@@ -479,8 +484,9 @@
   {
     CGAL_assertion (m_in != NULL);
 
-    int     c;
-    while ((c = m_in->get()) != EOF && c != '\n');
+    std::string line;
+    std::getline( *m_in, line );
+
     return;
   }
   
@@ -488,12 +494,15 @@
   void _skip_comments () 
   {
     CGAL_assertion (m_in != NULL);
-
-    int     c;
-    while ((c = m_in->get()) != EOF && c == '#')
-      _skip_until_EOL();
-    m_in->putback (c);
-
+    
+    std::string comment;
+    std::getline( *m_in, comment );
+    if ( comment.empty() )
+      return _skip_comments();
+    int s = comment[0];
+    if ( s == '\n' )
+      return _skip_comments();
+    CGAL_assertion ( s == '#' );
     return;
   }
 
// Using the arrangement I/O operators.

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

#include "arr_rational_nt.h"
#include <CGAL/Cartesian.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/IO/Arr_iostream.h>
#include <sstream>

#include "point_location_utils.h"

typedef CGAL::Cartesian<Number_type>                  Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel>            Traits_2;
typedef CGAL::Arrangement_2<Traits_2>                 Arrangement_2;

void test_arr_write_read( const Arrangement_2& arr1 )
{
  std::stringstream stream;
  stream << arr1;

  Arrangement_2 arr2;
  stream >> arr2;

  BOOST_REQUIRE( arr2.is_valid() );
  BOOST_CHECK_EQUAL( arr1.number_of_vertices(), arr2.number_of_vertices() );
  BOOST_CHECK_EQUAL( arr1.number_of_edges(), arr2.number_of_edges() );
  BOOST_CHECK_EQUAL( arr1.number_of_halfedges(), arr2.number_of_halfedges() );
  BOOST_CHECK_EQUAL( arr1.number_of_faces(), arr2.number_of_faces() );
  BOOST_CHECK_EQUAL( arr1.number_of_unbounded_faces(), arr2.number_of_unbounded_faces() );


  // write it again
  std::stringstream stream2;
  stream2 << arr2;

  Arrangement_2 arr3;
  stream2 >> arr3;

  BOOST_REQUIRE( arr3.is_valid() );
  BOOST_CHECK_EQUAL( arr1.number_of_vertices(), arr3.number_of_vertices() );
  BOOST_CHECK_EQUAL( arr1.number_of_edges(), arr3.number_of_edges() );
  BOOST_CHECK_EQUAL( arr1.number_of_halfedges(), arr3.number_of_halfedges() );
  BOOST_CHECK_EQUAL( arr1.number_of_faces(), arr3.number_of_faces() );
  BOOST_CHECK_EQUAL( arr1.number_of_unbounded_faces(), arr3.number_of_unbounded_faces() );

}

BOOST_AUTO_TEST_CASE( empty_arrangement_test )
{
  test_arr_write_read( Arrangement_2() );
}

BOOST_AUTO_TEST_CASE( filled_arrangement_test )
{
  // Construct the arrangement.
  Arrangement_2    arr;
  construct_segments_arr (arr);

  test_arr_write_read( arr );
}



Archive powered by MHonArc 2.6.16.

Top of Page