← Back to team overview

fenics-buildbot team mailing list archive

buildbot failure in FEniCS Project on dolfin-master-full-raring-amd64

 

The Buildbot has detected a new failure on builder dolfin-master-full-raring-amd64 while building FEniCS Project.
Full details are available at:
 http://fenicsproject.org:8010/builders/dolfin-master-full-raring-amd64/builds/270

Buildbot URL: http://fenicsproject.org:8010/

Buildslave for this Build: raring-amd64

Build Reason: 'try' job by user Johannes Ring
Build Source Stamp: HEAD (plus patch)
Blamelist: Johannes Ring

BUILD FAILED: failed make test

sincerely,
 -The Buildbot



diff --git a/demo/undocumented/csg/2D/cpp/main.cpp b/demo/undocumented/csg/2D/cpp/main.cpp
index ed6ee3e..3f185e8 100644
--- a/demo/undocumented/csg/2D/cpp/main.cpp
+++ b/demo/undocumented/csg/2D/cpp/main.cpp
@@ -31,24 +31,43 @@ using namespace dolfin;
 int main()
 {
   // Define 2D geometry
-  Rectangle r(0.5, 0.5, 1.5, 1.5);
-  Circle c(1, 1, 1);
-  boost::shared_ptr<CSGGeometry> g2d = c - r;
+  // Rectangle r(0.5, 0.5, 1.5, 1.5);
+  // Circle c(1, 1, 1);
+  // boost::shared_ptr<CSGGeometry> g2d = c - r;
+
+  // Define 2D geometry
+  Rectangle r1(0., 0., 5., 5.);
+  Rectangle r2 (2., 1.25, 3., 1.75);
+  Circle c1(1, 4, .25);
+  Circle c2(4, 4, .25);
+  boost::shared_ptr<CSGGeometry> domain =  r1 - r2 - c1 - c2;
+
+  Rectangle s1(1., 1., 4., 3.);
+  domain->set_subdomain(1, s1);
+
+  Rectangle s2(2., 2., 3., 4.);
+  domain->set_subdomain(2, s2);
+
 
   // Test printing
   info("\nCompact output of 2D geometry:");
-  info(*g2d);
+  info(*domain);
   info("");
   info("\nVerbose output of 2D geometry:");
-  info(*g2d, true);
+  info(*domain, true);
 
   // Plot geometry
-  plot(g2d, "2D Geometry (boundary)");
+  plot(domain, "2D Geometry (boundary)");
 
   // Generate and plot mesh
-  Mesh mesh2d(g2d, 100);
+  boost::shared_ptr<Mesh>  mesh2d(new Mesh(domain, 45));
   plot(mesh2d, "2D mesh");
 
+  // Convert mesh domains to mesh function for plotting
+  MeshFunction<std::size_t> mf(mesh2d, 2, mesh2d->domains());
+  plot(mf, "Subdomains");
+
+
   interactive();
   return 0;
 }
diff --git a/demo/undocumented/csg/2D/python/demo_csg_2D.py b/demo/undocumented/csg/2D/python/demo_csg_2D.py
index 3e5ee3f..d89704d 100644
--- a/demo/undocumented/csg/2D/python/demo_csg_2D.py
+++ b/demo/undocumented/csg/2D/python/demo_csg_2D.py
@@ -26,22 +26,28 @@ if not has_cgal():
 
 
 # Define 2D geometry
-r = Rectangle(0.5, 0.5, 1.5, 1.5);
-c = Circle (1, 1, 1);
-g2d = c - r;
+domain = Rectangle(0., 0., 5., 5.) - Rectangle(2., 1.25, 3., 1.75) - Circle(1, 4, .25) - Circle(4, 4, .25)
+domain.set_subdomain(1, Rectangle(1., 1., 4., 3.))
+domain.set_subdomain(2, Rectangle(2., 2., 3., 4.))
+
 
 # Test printing
 info("\nCompact output of 2D geometry:");
-info(g2d);
+info(domain);
 info("");
 info("\nVerbose output of 2D geometry:");
-info(g2d, True);
+info(domain, True);
 
 # Plot geometry
-plot(g2d, "2D Geometry (boundary)");
+plot(domain, "2D Geometry (boundary)");
 
 # Generate and plot mesh
-mesh2d = Mesh(g2d, 10);
-plot(mesh2d, "2D mesh");
+mesh2d = Mesh(domain, 45);
+plot(mesh2d, "2D mesh")
+
+# Convert subdomains to mesh function for plotting
+mf = MeshFunction("size_t", mesh2d, 2, mesh2d.domains())
+plot(mf, "Subdomains")
+
 
-interactive();
+interactive()
diff --git a/dolfin/generation/CSGCGALDomain2D.cpp b/dolfin/generation/CSGCGALDomain2D.cpp
new file mode 100644
index 0000000..3ec77fd
--- /dev/null
+++ b/dolfin/generation/CSGCGALDomain2D.cpp
@@ -0,0 +1,340 @@
+// Copyright (C) 2013 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2013-06-22
+// Last changed: 2013-08-06
+
+#include "CSGCGALDomain2D.h"
+#include "CSGPrimitives2D.h"
+#include "CSGOperators.h"
+#include <dolfin/common/constants.h>
+#include <dolfin/log/LogStream.h>
+
+#include <CGAL/basic.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/Boolean_set_operations_2.h>
+#include <CGAL/Polygon_set_2.h>
+
+#include <CGAL/Min_circle_2.h>
+#include <CGAL/Min_circle_2_traits_2.h>
+
+// Polygon typedefs
+typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_Kernel;
+typedef Exact_Kernel::Point_2                             Point_2;
+typedef CGAL::Polygon_2<Exact_Kernel>                     Polygon_2;
+typedef Polygon_2::Vertex_const_iterator                  Vertex_const_iterator;
+typedef CGAL::Polygon_with_holes_2<Exact_Kernel>          Polygon_with_holes_2;
+typedef Polygon_with_holes_2::Hole_const_iterator         Hole_const_iterator;
+typedef CGAL::Polygon_set_2<Exact_Kernel>                 Polygon_set_2;
+
+// Min enclosing circle typedefs
+typedef CGAL::Min_circle_2_traits_2<Exact_Kernel>  Min_Circle_Traits;
+typedef CGAL::Min_circle_2<Min_Circle_Traits>      Min_circle;
+typedef CGAL::Circle_2<Exact_Kernel> CGAL_Circle;
+
+using namespace dolfin;
+
+struct CSGCGALDomain2DImpl
+{
+  Polygon_set_2 polygon_set;
+
+  CSGCGALDomain2DImpl(){}
+  CSGCGALDomain2DImpl(const Polygon_set_2& p)
+    : polygon_set(p) {}
+};
+//-----------------------------------------------------------------------------
+Polygon_2 make_circle(const Circle* c)
+{
+  std::vector<Point_2> pts;
+  pts.reserve(c->fragments());
+
+  for (std::size_t i = 0; i < c->fragments(); i++)
+  {
+    const double phi = (2*DOLFIN_PI*i) / c->fragments();
+    const double x = c->center().x() + c->radius()*cos(phi);
+    const double y = c->center().y() + c->radius()*sin(phi);
+    pts.push_back(Point_2(x, y));
+  }
+
+  return Polygon_2(pts.begin(), pts.end());
+}
+//-----------------------------------------------------------------------------
+Polygon_2 make_ellipse(const Ellipse* e)
+{
+  std::vector<Point_2> pts;
+
+  for (std::size_t i = 0; i < e->fragments(); i++)
+  {
+    const double phi = (2*DOLFIN_PI*i) / e->fragments();
+    const double x = e->center().x() + e->a()*cos(phi);
+    const double y = e->center().y() + e->b()*sin(phi);
+    pts.push_back(Point_2(x, y));
+  }
+
+  return Polygon_2(pts.begin(), pts.end());
+}
+//-----------------------------------------------------------------------------
+Polygon_2 make_rectangle(const Rectangle* r)
+{
+  const double x0 = std::min(r->first_corner().x(), r->second_corner().x());
+  const double y0 = std::min(r->first_corner().y(), r->second_corner().y());
+
+  const double x1 = std::max(r->first_corner().x(), r->second_corner().x());
+  const double y1 = std::max(r->first_corner().y(), r->second_corner().y());
+
+  std::vector<Point_2> pts;
+  pts.push_back(Point_2(x0, y0));
+  pts.push_back(Point_2(x1, y0));
+  pts.push_back(Point_2(x1, y1));
+  pts.push_back(Point_2(x0, y1));
+
+  Polygon_2 p(pts.begin(), pts.end());
+  
+  return p;
+}
+//-----------------------------------------------------------------------------
+Polygon_2 make_polygon(const Polygon* p)
+{
+  std::vector<Point_2> pts;
+  std::vector<Point>::const_iterator v;
+  for (v = p->vertices().begin(); v != p->vertices().end(); ++v)
+    pts.push_back(Point_2(v->x(), v->y()));
+
+  return Polygon_2(pts.begin(), pts.end());
+}
+//-----------------------------------------------------------------------------
+CSGCGALDomain2D::CSGCGALDomain2D()
+  : impl(new CSGCGALDomain2DImpl)
+{
+  
+}
+//-----------------------------------------------------------------------------
+CSGCGALDomain2D::~CSGCGALDomain2D()
+{
+}
+//-----------------------------------------------------------------------------
+CSGCGALDomain2D::CSGCGALDomain2D(const CSGGeometry *geometry)
+: impl(new CSGCGALDomain2DImpl)
+{
+  switch (geometry->getType()) 
+  {
+    case CSGGeometry::Union:
+    {
+      const CSGUnion *u = dynamic_cast<const CSGUnion*>(geometry);
+      dolfin_assert(u);
+
+      CSGCGALDomain2D a(u->_g0.get());
+      CSGCGALDomain2D b(u->_g1.get());
+
+      impl.swap(a.impl);
+      impl->polygon_set.join(b.impl->polygon_set);    
+      break;
+    }
+    case CSGGeometry::Intersection:
+    {
+      const CSGIntersection* u = dynamic_cast<const CSGIntersection*>(geometry);
+      dolfin_assert(u);
+
+      CSGCGALDomain2D a(u->_g0.get());
+      CSGCGALDomain2D b(u->_g1.get());
+      
+      impl.swap(a.impl);
+      impl->polygon_set.intersection(b.impl->polygon_set);
+      break;
+    }
+    case CSGGeometry::Difference:
+    {
+      const CSGDifference* u = dynamic_cast<const CSGDifference*>(geometry);
+      dolfin_assert(u);
+      CSGCGALDomain2D a(u->_g0.get());
+      CSGCGALDomain2D b(u->_g1.get());
+      
+      impl.swap(a.impl);
+      impl->polygon_set.difference(b.impl->polygon_set);
+      break;
+    }
+    case CSGGeometry::Circle:
+    {
+      const Circle* c = dynamic_cast<const Circle*>(geometry);
+      dolfin_assert(c);
+      impl->polygon_set.insert(make_circle(c));
+      break;
+    }
+    case CSGGeometry::Ellipse:
+    {
+      const Ellipse* c = dynamic_cast<const Ellipse*>(geometry);
+      dolfin_assert(c);
+      impl->polygon_set.insert(make_ellipse(c));
+      break;
+    }
+    case CSGGeometry::Rectangle:
+    {
+      const Rectangle* r = dynamic_cast<const Rectangle*>(geometry);
+      dolfin_assert(r);
+      impl->polygon_set.insert(make_rectangle(r));
+      break;
+    }
+    case CSGGeometry::Polygon:
+    {
+      const Polygon* p = dynamic_cast<const Polygon*>(geometry);
+      dolfin_assert(p);
+      impl->polygon_set.insert(make_polygon(p));
+      break;
+    }
+    default:
+      dolfin_error("CSGCGALMeshGenerator2D.cpp",
+                   "converting geometry to cgal polyhedron",
+                   "Unhandled primitive type");
+  }
+}
+//-----------------------------------------------------------------------------
+CSGCGALDomain2D::CSGCGALDomain2D(const CSGCGALDomain2D &other)
+ : impl(new CSGCGALDomain2DImpl(other.impl->polygon_set))
+{
+}
+//-----------------------------------------------------------------------------
+CSGCGALDomain2D &CSGCGALDomain2D::operator=(const CSGCGALDomain2D &other)
+{
+  boost::scoped_ptr<CSGCGALDomain2DImpl> tmp(new CSGCGALDomain2DImpl(other.impl->polygon_set));
+  
+  impl.swap(tmp);
+
+  return *this;
+}
+//-----------------------------------------------------------------------------
+double CSGCGALDomain2D::compute_boundingcircle_radius() const
+{
+  std::list<Polygon_with_holes_2> polygon_list;
+  impl->polygon_set.polygons_with_holes(std::back_inserter(polygon_list));
+
+  std::vector<Point_2> points;
+
+  for (std::list<Polygon_with_holes_2>::const_iterator pit = polygon_list.begin();
+       pit != polygon_list.end(); ++pit)
+    for (Polygon_2::Vertex_const_iterator vit = pit->outer_boundary().vertices_begin(); 
+         vit != pit->outer_boundary().vertices_end(); ++vit)
+      points.push_back(*vit);
+
+  Min_circle min_circle (points.begin(),
+                         points.end(),
+                         true); //randomize point order
+
+  return sqrt(CGAL::to_double(min_circle.circle().squared_radius()));
+}
+//-----------------------------------------------------------------------------
+void CSGCGALDomain2D::join_inplace(const CSGCGALDomain2D& other)
+{
+  impl->polygon_set.join(other.impl->polygon_set);
+}
+//-----------------------------------------------------------------------------
+void CSGCGALDomain2D::difference_inplace(const CSGCGALDomain2D& other)
+{
+  impl->polygon_set.difference(other.impl->polygon_set);
+}
+//-----------------------------------------------------------------------------
+void CSGCGALDomain2D::intersect_inplace(const CSGCGALDomain2D &other)
+{
+  impl->polygon_set.intersection(other.impl->polygon_set);
+}
+//-----------------------------------------------------------------------------
+bool CSGCGALDomain2D::point_in_domain(Point p) const
+{
+  const Point_2 p_(p.x(), p.y());
+  return impl->polygon_set.oriented_side(p_) == CGAL::ON_POSITIVE_SIDE;
+}
+//-----------------------------------------------------------------------------
+void CSGCGALDomain2D::get_vertices(std::list<std::vector<Point> >& l, 
+                                   double truncate_threshold) const
+{
+  l.clear();
+
+  truncate_threshold *= truncate_threshold;
+
+  std::list<Polygon_with_holes_2> polygon_list;
+  impl->polygon_set.polygons_with_holes(std::back_inserter(polygon_list));
+  
+  std::list<Polygon_with_holes_2>::const_iterator pit;
+  for (pit = polygon_list.begin(); pit != polygon_list.end(); ++pit)
+  {
+    const Polygon_2 &outer = pit->outer_boundary();
+
+    l.push_back(std::vector<Point>());
+    std::vector<Point> &v = l.back();
+    v.reserve(outer.size());
+
+    Polygon_2::Vertex_const_iterator prev = outer.vertices_begin(); 
+    Polygon_2::Vertex_const_iterator current = prev;
+    ++current;
+    for (; current != outer.vertices_end(); ++current)
+    {
+      if ( (*current - *prev).squared_length() < truncate_threshold)
+        continue;
+
+      const double x = CGAL::to_double(current->x());
+      const double y = CGAL::to_double(current->y());
+      v.push_back(Point(x, y));
+
+      prev = current;
+    }
+  
+    current = outer.vertices_begin();
+    if ( (*current - *prev).squared_length() > truncate_threshold)
+      v.push_back(Point(CGAL::to_double(current->x()), 
+                        CGAL::to_double(current->y())));
+  }
+}
+//-----------------------------------------------------------------------------
+void CSGCGALDomain2D::get_holes(std::list<std::vector<Point> >& h,
+                                double truncate_threshold) const
+{
+  h.clear();
+
+  std::list<Polygon_with_holes_2> polygon_list;
+  impl->polygon_set.polygons_with_holes(std::back_inserter(polygon_list));
+
+  std::list<Polygon_with_holes_2>::const_iterator pit;
+  for (pit = polygon_list.begin(); pit != polygon_list.end(); ++pit)
+  {
+    Hole_const_iterator hit;
+    for (hit = pit->holes_begin(); hit != pit->holes_end(); ++hit)
+    {
+      h.push_back(std::vector<Point>());
+      std::vector<Point> &v = h.back();
+      v.reserve(hit->size());
+
+      Polygon_2::Vertex_const_iterator prev = hit->vertices_begin(); 
+      Polygon_2::Vertex_const_iterator current = prev;
+      ++current;
+
+      for (; current != hit->vertices_end(); ++current)
+      {
+        if ( (*current - *prev).squared_length() < truncate_threshold)
+          continue;
+
+        const double x = CGAL::to_double(current->x());
+        const double y = CGAL::to_double(current->y());
+        v.push_back(Point(x, y));
+
+        prev = current;
+      }
+      current = hit->vertices_begin();
+      if ( (*current - *prev).squared_length() > truncate_threshold)
+        v.push_back(Point(CGAL::to_double(current->x()), 
+                          CGAL::to_double(current->y())));
+    }
+  }
+}
diff --git a/dolfin/generation/CSGCGALDomain2D.h b/dolfin/generation/CSGCGALDomain2D.h
new file mode 100644
index 0000000..ed25f9a
--- /dev/null
+++ b/dolfin/generation/CSGCGALDomain2D.h
@@ -0,0 +1,67 @@
+// Copyright (C) 2013 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2013-06-22
+// Last changed: 2013-08-06
+
+#include "CSGGeometry.h"
+
+#include <dolfin/geometry/Point.h>
+#include <boost/scoped_ptr.hpp>
+
+struct CSGCGALDomain2DImpl;
+
+namespace dolfin
+{
+
+class CSGCGALDomain2D
+{
+ public:
+  // Create empty polygon
+  CSGCGALDomain2D();
+
+  // Construct polygon from Dolfin CSG geometry
+  CSGCGALDomain2D(const CSGGeometry *csg);
+
+  // Destructor
+  ~CSGCGALDomain2D();
+
+  // Copy constructor
+  CSGCGALDomain2D(const CSGCGALDomain2D &other);
+  CSGCGALDomain2D &operator=(const CSGCGALDomain2D &other);
+
+  // Boolean operators
+  void join_inplace(const CSGCGALDomain2D& other);
+  void intersect_inplace(const CSGCGALDomain2D& other);
+  void difference_inplace(const CSGCGALDomain2D& other);
+
+  bool point_in_domain(Point p) const;
+  double compute_boundingcircle_radius() const ;
+  
+  // TODO: Replace this with a more C++-ish
+  // implementation, ie, take an outputiterator as arugment
+  // or define iterator
+  void get_vertices(std::list<std::vector<Point> >& v, 
+                    double truncate_threshold) const;
+
+  void get_holes(std::list<std::vector<Point> >& h, 
+                 double truncate_threshold) const;
+
+  boost::scoped_ptr<CSGCGALDomain2DImpl> impl;
+
+};
+}
diff --git a/dolfin/generation/CSGCGALMeshGenerator2D.cpp b/dolfin/generation/CSGCGALMeshGenerator2D.cpp
index 8fb71d9..adb2a21 100644
--- a/dolfin/generation/CSGCGALMeshGenerator2D.cpp
+++ b/dolfin/generation/CSGCGALMeshGenerator2D.cpp
@@ -19,34 +19,32 @@
 // Modified by Benjamin Kehlet 2012-2013
 //
 // First added:  2012-05-10
-// Last changed: 2013-03-15
+// Last changed: 2013-08-06
 
-#include <vector>
-#include <cmath>
+#include "CSGCGALMeshGenerator2D.h"
+#include "CSGGeometry.h"
+#include "CSGOperators.h"
+#include "CSGPrimitives2D.h"
+#include "CSGCGALDomain2D.h"
 
 #include <dolfin/common/constants.h>
 #include <dolfin/math/basic.h>
 #include <dolfin/mesh/Mesh.h>
 #include <dolfin/mesh/MeshEditor.h>
+#include <dolfin/mesh/MeshFunction.h>
+#include <dolfin/mesh/MeshDomains.h>
+#include <dolfin/mesh/MeshValueCollection.h>
+#include <dolfin/log/log.h>
 
-#include "CSGCGALMeshGenerator2D.h"
-#include "CSGGeometry.h"
-#include "CSGOperators.h"
-#include "CSGPrimitives2D.h"
 
-#ifdef HAS_CGAL
-#include "CGALMeshBuilder.h"
+#include <vector>
+#include <cmath>
+#include <limits>
+
 
-#include <CGAL/basic.h>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#ifdef HAS_CGAL
 #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
 
-#include <CGAL/Gmpq.h>
-#include <CGAL/Lazy_exact_nt.h>
-#include <CGAL/Simple_cartesian.h>
-#include <CGAL/Bounded_kernel.h>
-#include <CGAL/Nef_polyhedron_2.h>
-#include <CGAL/Polygon_2.h>
 #include <CGAL/Triangulation_vertex_base_with_info_2.h>
 #include <CGAL/Constrained_Delaunay_triangulation_2.h>
 #include <CGAL/Triangulation_face_base_with_info_2.h>
@@ -54,47 +52,21 @@
 #include <CGAL/Delaunay_mesh_face_base_2.h>
 #include <CGAL/Delaunay_mesh_size_criteria_2.h>
 
-#include <CGAL/Min_circle_2.h>
-#include <CGAL/Min_circle_2_traits_2.h>
-
-typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_Kernel;
 typedef CGAL::Exact_predicates_inexact_constructions_kernel Inexact_Kernel;
 
-typedef CGAL::Lazy_exact_nt<CGAL::Gmpq> FT;
-typedef CGAL::Simple_cartesian<FT> EKernel;
-typedef CGAL::Bounded_kernel<EKernel> Extended_kernel;
-typedef CGAL::Nef_polyhedron_2<Extended_kernel> Nef_polyhedron_2;
-typedef Nef_polyhedron_2::Point Nef_point_2;
-
-typedef Nef_polyhedron_2::Explorer Explorer;
-typedef Explorer::Face_const_iterator Face_const_iterator;
-typedef Explorer::Hole_const_iterator Hole_const_iterator;
-typedef Explorer::Vertex_const_iterator Vertex_const_iterator;
-typedef Explorer::Halfedge_around_face_const_circulator
-           Halfedge_around_face_const_circulator;
-typedef Explorer::Vertex_const_handle Vertex_const_handle;
-typedef Explorer::Halfedge_const_handle Halfedge_const_handle;
-
 typedef CGAL::Triangulation_vertex_base_2<Inexact_Kernel>  Vertex_base;
 typedef CGAL::Constrained_triangulation_face_base_2<Inexact_Kernel> Face_base;
 
-// Min enclosing circle typedefs
-typedef CGAL::Min_circle_2_traits_2<Extended_kernel>  Min_Circle_Traits;
-typedef CGAL::Min_circle_2<Min_Circle_Traits>      Min_circle;
-typedef CGAL::Circle_2<Extended_kernel> CGAL_Circle;
-
-
-template <class Gt,
-          class Fb >
-class Enriched_face_base_2 : public Fb
+template <class Gt, class Fb >
+class Enriched_face_base_2 : public Fb 
 {
-public:
+ public:
   typedef Gt Geom_traits;
   typedef typename Fb::Vertex_handle Vertex_handle;
   typedef typename Fb::Face_handle Face_handle;
 
-  template < typename TDS2 >
-  struct Rebind_TDS
+  template <typename TDS2>
+  struct Rebind_TDS 
   {
     typedef typename Fb::template Rebind_TDS<TDS2>::Other Fb2;
     typedef Enriched_face_base_2<Gt,Fb2> Other;
@@ -102,24 +74,33 @@ public:
 
 protected:
   int status;
+  bool in_domain;
 
 public:
   Enriched_face_base_2(): Fb(), status(-1) {}
 
-  Enriched_face_base_2(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2)
-    : Fb(v0,v1,v2), status(-1) {}
+  Enriched_face_base_2(Vertex_handle v0,
+                       Vertex_handle v1,
+                       Vertex_handle v2)
+    : Fb(v0,v1,v2), status(-1), in_domain(true) {}
 
-  Enriched_face_base_2(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2,
-                       Face_handle n0, Face_handle n1, Face_handle n2)
-    : Fb(v0,v1,v2,n0,n1,n2), status(-1) {}
+  Enriched_face_base_2(Vertex_handle v0,
+                       Vertex_handle v1,
+                       Vertex_handle v2,
+                       Face_handle n0,
+                       Face_handle n1,
+                       Face_handle n2)
+    : Fb(v0,v1,v2,n0,n1,n2), status(-1), in_domain(true) {}
 
   inline
   bool is_in_domain() const
-  { return (status%2 == 1); }
+  //{ return (status%2 == 1); }
+  { return in_domain; }
 
   inline
   void set_in_domain(const bool b)
-  { status = (b ? 1 : 0); }
+  //{ status = (b ? 1 : 0); }
+  { in_domain = b; }
 
   inline
   void set_counter(int i)
@@ -147,253 +128,274 @@ typedef CDT::Vertex_handle Vertex_handle;
 typedef CDT::Face_handle Face_handle;
 typedef CDT::All_faces_iterator All_faces_iterator;
 
-typedef CGAL::Polygon_2<Inexact_Kernel> Polygon_2;
 typedef Inexact_Kernel::Point_2 Point_2;
 
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
 CSGCGALMeshGenerator2D::CSGCGALMeshGenerator2D(const CSGGeometry& geometry)
-  : _geometry(geometry)
+: geometry(geometry)
 {
   parameters = default_parameters();
+  //subdomains.push_back(reference_to_no_delete_pointer(geometry));
 }
 //-----------------------------------------------------------------------------
 CSGCGALMeshGenerator2D::~CSGCGALMeshGenerator2D() {}
 //-----------------------------------------------------------------------------
-Nef_polyhedron_2 make_circle(const Circle* c)
-{
-  std::vector<Nef_point_2> pts;
-
-  for (std::size_t i = 0; i < c->fragments(); i++)
-  {
-    const double phi = (2*DOLFIN_PI*i) / c->fragments();
-    const double x = c->center().x() + c->radius()*cos(phi);
-    const double y = c->center().y() + c->radius()*sin(phi);
-    pts.push_back(Nef_point_2(x, y));
-  }
 
-  return Nef_polyhedron_2(pts.begin(), pts.end(), Nef_polyhedron_2::INCLUDED);
-}
 //-----------------------------------------------------------------------------
-Nef_polyhedron_2 make_ellipse(const Ellipse* e)
-{
-  std::vector<Nef_point_2> pts;
-
-  for (std::size_t i = 0; i < e->fragments(); i++)
-  {
-    const double phi = (2*DOLFIN_PI*i) / e->fragments();
-    const double x = e->center().x() + e->a()*cos(phi);
-    const double y = e->center().y() + e->b()*sin(phi);
-    pts.push_back(Nef_point_2(x, y));
-  }
-
-  return Nef_polyhedron_2(pts.begin(), pts.end(), Nef_polyhedron_2::INCLUDED);
-}
+//static void print_edge(CDT::Edge edge)
+//{
+//  const int i = edge.second;
+//  std::cout << "Edge: (" << edge.first->vertex( (i+1)%3 )->point()
+//            << "), (" << edge.first->vertex( (i+2)%3 )->point() << ")" << std::endl;
+//}
+////-----------------------------------------------------------------------------
+//static void print_face(const CDT::Face_handle f)
+//{
+//    std::cout << "Face:" << std::endl;
+//    std::cout << "  " << f->vertex(0)->point() << std::endl;
+//    std::cout << "  " << f->vertex(1)->point() << std::endl;
+//    std::cout << "  " << f->vertex(2)->point() << std::endl;
+//    std::cout << "  " << (f->is_in_domain() ? "In domain" : "Not in domain") << std::endl;
+//}
 //-----------------------------------------------------------------------------
-Nef_polyhedron_2 make_rectangle(const Rectangle* r)
+//// print the faces of a triangulation
+//static void print_triangulation(const CDT &cdt)
+//{
+//  for (  CDT::Finite_faces_iterator it = cdt.finite_faces_begin();
+//         it != cdt.finite_faces_end(); ++it)
+//  {
+//    print_face(it);
+//  }
+//}
+////-----------------------------------------------------------------------------
+//static void print_constrained_edges(const CDT& cdt)
+//{
+//  std::cout << "-- Constrained edges" << std::endl;
+//
+//  for (CDT::Finite_edges_iterator it = cdt.finite_edges_begin();
+//       it != cdt.finite_edges_end();
+//       it++)
+//  {
+//      if (cdt.is_constrained(*it))
+//        print_edge(*it);
+//  }
+//
+//  std::cout << "--" << std::endl;
+//}
+//-----------------------------------------------------------------------------
+void explore_subdomain(CDT &ct,
+                        CDT::Face_handle start, 
+                        std::list<CDT::Face_handle>& other_domains)
 {
-  const double x0 = std::min(r->first_corner().x(), r->first_corner().y());
-  const double y0 = std::max(r->first_corner().x(), r->first_corner().y());
+  std::list<Face_handle> queue;
+  queue.push_back(start);
 
-  const double x1 = std::min(r->second_corner().x(), r->second_corner().y());
-  const double y1 = std::max(r->second_corner().x(), r->second_corner().y());
+  while (!queue.empty())
+  {
+    CDT::Face_handle face = queue.front();
+    queue.pop_front();
 
-  std::vector<Nef_point_2> pts;
-  pts.push_back(Nef_point_2(x0, x1));
-  pts.push_back(Nef_point_2(y0, x1));
-  pts.push_back(Nef_point_2(y0, y1));
-  pts.push_back(Nef_point_2(x0, y1));
+    for(int i = 0; i < 3; i++) 
+    {
+      Face_handle n = face->neighbor(i);
+      if (ct.is_infinite(n))
+        continue;
 
-  return Nef_polyhedron_2(pts.begin(), pts.end(), Nef_polyhedron_2::INCLUDED);
-}
-//-----------------------------------------------------------------------------
-Nef_polyhedron_2 make_polygon(const Polygon* p)
-{
-  std::vector<Nef_point_2> pts;
-  std::vector<Point>::const_iterator v;
-  for (v = p->vertices().begin(); v != p->vertices().end(); ++v)
-    pts.push_back(Nef_point_2(v->x(), v->y()));
+      const CDT::Edge e(face,i);
 
-  return Nef_polyhedron_2(pts.begin(), pts.end(), Nef_polyhedron_2::INCLUDED);
+      if (n->counter() == -1)
+      {
+        if (ct.is_constrained(e))
+        {
+          // Reached a border
+          other_domains.push_back(n);
+        } else
+        {
+          // Set neighbor interface to the same and push to queue
+          n->set_counter(face->counter());
+          n->set_in_domain(face->is_in_domain());
+          queue.push_back(n);
+        }
+      }
+    }
+  }
 }
 //-----------------------------------------------------------------------------
-static Nef_polyhedron_2 convertSubTree(const CSGGeometry *geometry)
+// Set the member in_domain and counter for all faces in the cdt
+void explore_subdomains(CDT& cdt, 
+                        const CSGCGALDomain2D& total_domain,
+                        const std::vector<std::pair<std::size_t, CSGCGALDomain2D> > &subdomain_geometries)
 {
-  switch (geometry->getType()) {
-  case CSGGeometry::Union:
-  {
-    const CSGUnion* u = dynamic_cast<const CSGUnion*>(geometry);
-    dolfin_assert(u);
-    return convertSubTree(u->_g0.get()) + convertSubTree(u->_g1.get());
-    break;
-  }
-  case CSGGeometry::Intersection:
-  {
-    const CSGIntersection* u = dynamic_cast<const CSGIntersection*>(geometry);
-    dolfin_assert(u);
-    return convertSubTree(u->_g0.get()) * convertSubTree(u->_g1.get());
-    break;
-  }
-  case CSGGeometry::Difference:
-  {
-    const CSGDifference* u = dynamic_cast<const CSGDifference*>(geometry);
-    dolfin_assert(u);
-    return convertSubTree(u->_g0.get()) - convertSubTree(u->_g1.get());
-    break;
-  }
-  case CSGGeometry::Circle:
+  // Set counter to -1 for all faces
+  for (CDT::Finite_faces_iterator it = cdt.finite_faces_begin(); it != cdt.finite_faces_end(); ++it)
   {
-    const Circle* c = dynamic_cast<const Circle*>(geometry);
-    dolfin_assert(c);
-    return make_circle(c);
-    break;
-  }
-  case CSGGeometry::Ellipse:
-  {
-    const Ellipse* c = dynamic_cast<const Ellipse*>(geometry);
-    dolfin_assert(c);
-    return make_ellipse(c);
-    break;
-  }
-  case CSGGeometry::Rectangle:
-  {
-    const Rectangle* r = dynamic_cast<const Rectangle*>(geometry);
-    dolfin_assert(r);
-    return make_rectangle(r);
-    break;
+    it->set_counter(-1);
+    it->set_in_domain(false);
   }
-  case CSGGeometry::Polygon:
+
+  std::list<CDT::Face_handle> subdomains;
+  subdomains.push_back(cdt.finite_faces_begin());
+
+  //print_face(subdomains.front());
+  //dolfin_assert(face_in_domain(subdomains.front(), total_domain));
+
+  while (!subdomains.empty())
   {
-    const Polygon* p = dynamic_cast<const Polygon*>(geometry);
-    dolfin_assert(p);
-    return make_polygon(p);
-    break;
-  }
-  default:
-    dolfin_error("CSGCGALMeshGenerator2D.cpp",
-                 "converting geometry to cgal polyhedron",
-                 "Unhandled primitive type");
+    const CDT::Face_handle f = subdomains.front();
+    subdomains.pop_front();
+
+    if (f->counter() < 0)
+    {
+      // Set default marker (0)
+      f->set_counter(0);
+
+      const Point_2 p0 = f->vertex(0)->point();
+      const Point_2 p1 = f->vertex(1)->point();
+      const Point_2 p2 = f->vertex(2)->point();
+
+      Point p( (p0[0] + p1[0] + p2[0]) / 3.0,
+               (p0[1] + p1[1] + p2[1]) / 3.0 );
+
+      // Set the in_domain member (is face in the total domain)
+      f->set_in_domain(total_domain.point_in_domain(p));
+
+      for (int i = subdomain_geometries.size(); i > 0; --i)
+      {
+        if (subdomain_geometries[i-1].second.point_in_domain(p))
+        {
+          f->set_counter(subdomain_geometries[i-1].first);
+          break;
+        } 
+      }
+      
+      explore_subdomain(cdt, f, subdomains);
+    }
   }
-  return Nef_polyhedron_2();
 }
 //-----------------------------------------------------------------------------
-// Taken from examples/Triangulation_2/polygon_triangulation.cpp in the
-// CGAL source tree.
-//
-// Explore set of facets connected with non constrained edges, and
-// attribute to each such set a counter.  We start from facets
-// incident to the infinite vertex, with a counter set to 0. Then we
-// recursively consider the non-explored facets incident to
-// constrained edges bounding the former set and increase thecounter
-// by 1.  Facets in the domain are those with an odd nesting level.
-void mark_domains(CDT& ct,
-                  CDT::Face_handle start,
-                  int index,
-                  std::list<CDT::Edge>& border)
+  // Insert edges from polygon as constraints in the triangulation
+void add_subdomain(CDT& cdt, const CSGCGALDomain2D& cgal_geometry, double threshold)
 {
-  if (start->counter() != -1)
-    return;
 
-  std::list<CDT::Face_handle> queue;
-  queue.push_back(start);
+  // Insert the outer boundaries of the domain
+  {
+    std::list<std::vector<Point> > v;
+    cgal_geometry.get_vertices(v, threshold);
 
-  while (!queue.empty())
+    for (std::list<std::vector<Point> >::const_iterator pit = v.begin();
+         pit != v.end(); ++pit)
+    {
+      std::vector<Point>::const_iterator it = pit->begin();
+      Vertex_handle first = cdt.insert(Point_2(it->x(), it->y()));
+      Vertex_handle prev = first;
+      ++it;
+
+      for(; it != pit->end(); ++it)
+      {
+        Vertex_handle current = cdt.insert(Point_2(it->x(), it->y()));
+        cdt.insert_constraint(prev, current);
+        prev = current;
+      }
+
+      cdt.insert_constraint(first, prev);
+    }
+  }
+
+  // Insert holes
   {
-    CDT::Face_handle fh = queue.front();
-    queue.pop_front();
-    if (fh->counter() == -1)
+    std::list<std::vector<Point> > holes;
+    cgal_geometry.get_holes(holes, threshold);
+
+    for (std::list<std::vector<Point> >::const_iterator hit = holes.begin();
+         hit != holes.end(); ++hit)
     {
-      fh->counter() = index;
-      fh->set_in_domain(index%2 == 1);
-      for (int i = 0; i < 3; i++)
+
+      std::vector<Point>::const_iterator pit = hit->begin();
+      Vertex_handle first = cdt.insert(Point_2(pit->x(), pit->y()));
+      Vertex_handle prev = first;
+      ++pit;
+
+      for(; pit != hit->end(); ++pit)
       {
-        CDT::Edge e(fh, i);
-        CDT::Face_handle n = fh->neighbor(i);
-        if (n->counter() == -1)
-        {
-          if (ct.is_constrained(e))
-            border.push_back(e);
-          else
-            queue.push_back(n);
-        }
+        Vertex_handle current = cdt.insert(Point_2(pit->x(), pit->y()));
+        cdt.insert_constraint(prev, current);
+        prev = current;
       }
+
+      cdt.insert_constraint(first, prev);
     }
   }
 }
 //-----------------------------------------------------------------------------
-void mark_domains(CDT& cdt)
+double shortest_constrained_edge(const CDT &cdt)
 {
-  for (CDT::All_faces_iterator it = cdt.all_faces_begin();
-       it != cdt.all_faces_end(); ++it)
+  double min_length = std::numeric_limits<double>::max();
+  for (CDT::Finite_edges_iterator it = cdt.finite_edges_begin();
+       it != cdt.finite_edges_end();
+       it++)
   {
-    it->set_counter(-1);
-  }
+    if (!cdt.is_constrained(*it))
+      continue;
 
-  int index = 0;
-  std::list<CDT::Edge> border;
-  mark_domains(cdt, cdt.infinite_face(), index++, border);
-  while (!border.empty())
-  {
-    CDT::Edge e = border.front();
-    border.pop_front();
-    CDT::Face_handle n = e.first->neighbor(e.second);
-    if (n->counter() == -1)
-      mark_domains(cdt, n, e.first->counter()+1, border);
+    // An edge is an std::pair<Face_handle, int>
+    // see CGAL/Triangulation_data_structure_2.h
+    CDT::Face_handle f = it->first;
+    const int i = it->second;
+
+    CDT::Point p1 = f->vertex( (i+1)%3 )->point();
+    CDT::Point p2 = f->vertex( (i+2)%3 )->point();
+
+    min_length = std::min(CGAL::to_double((p1-p2).squared_length()), min_length);
   }
+
+  return min_length;
 }
 //-----------------------------------------------------------------------------
 void CSGCGALMeshGenerator2D::generate(Mesh& mesh)
 {
-  Nef_polyhedron_2 cgal_geometry = convertSubTree(&_geometry);
-
   // Create empty CGAL triangulation
   CDT cdt;
 
-  // Explore the Nef polyhedron and insert constraints in the
-  // triangulation
-  Explorer explorer = cgal_geometry.explorer();
-  for (Face_const_iterator fit = explorer.faces_begin() ;
-       fit != explorer.faces_end(); fit++)
+  // Convert the CSG geometry to a CGAL Polygon
+  log(TRACE, "Converting geometry to CGAL polygon");
+  CSGCGALDomain2D total_domain(&geometry);
+
+  add_subdomain(cdt, total_domain, parameters["edge_minimum"]);
+
+  // Empty polygon, will be populated when traversing the subdomains
+  CSGCGALDomain2D overlaying;
+
+  std::vector<std::pair<std::size_t, CSGCGALDomain2D> > 
+    subdomain_geometries;
+
+  // Add the subdomains to the CDT. Traverse in reverse order to get the latest
+  // added subdomain on top
+  std::list<std::pair<std::size_t, boost::shared_ptr<const CSGGeometry> > >::const_reverse_iterator it;
+
+  if (!geometry.subdomains.empty())
+    log(TRACE, "Processing subdomains");
+
+  for (it = geometry.subdomains.rbegin(); it != geometry.subdomains.rend(); ++it)
   {
-    // Skip face if it is not part of polygon
-    if (!explorer.mark(fit))
-      continue;
+    const std::size_t current_index = it->first;
+    boost::shared_ptr<const CSGGeometry> current_subdomain = it->second;
 
-    Halfedge_around_face_const_circulator hafc
-      = explorer.face_cycle(fit), done(hafc);
-    do
-    {
-      Vertex_handle va
-        = cdt.insert(Point_2(to_double(hafc->vertex()->point().x()),
-                             to_double(hafc->vertex()->point().y())));
-      Vertex_handle vb
-        = cdt.insert(Point_2(to_double(hafc->next()->vertex()->point().x()),
-                             to_double(hafc->next()->vertex()->point().y())));
-      cdt.insert_constraint(va, vb);
-      hafc++;
-    } while (hafc != done);
-
-    Hole_const_iterator hit = explorer.holes_begin(fit);
-    for (; hit != explorer.holes_end(fit); hit++)
-    {
-      Halfedge_around_face_const_circulator hafc1(hit), done1(hit);
-      do
-      {
-        Vertex_handle va
-          = cdt.insert(Point_2(to_double(hafc1->vertex()->point().x()),
-                               to_double(hafc1->vertex()->point().y())));
-        Vertex_handle vb
-          = cdt.insert(Point_2(to_double(hafc1->next()->vertex()->point().x()),
-                            to_double(hafc1->next()->vertex()->point().y())));
-        cdt.insert_constraint(va, vb);
-        hafc1++;
-      } while (hafc1 != done1);
-    }
+    CSGCGALDomain2D cgal_geometry(current_subdomain.get());
+    cgal_geometry.difference_inplace(overlaying);
+    
+    subdomain_geometries.push_back(std::make_pair(current_index, 
+                                                  cgal_geometry));
+
+    add_subdomain(cdt, cgal_geometry, parameters["edge_minimum"]);
+
+    overlaying.join_inplace(cgal_geometry);
   }
 
-  // Mark parts that are inside and outside the domain
-  mark_domains(cdt);
+  explore_subdomains(cdt, total_domain, subdomain_geometries);
+
+  log(TRACE, "Refining mesh");
 
   // Create mesher
   CGAL_Mesher_2 mesher(cdt);
@@ -411,34 +413,25 @@ void CSGCGALMeshGenerator2D::generate(Mesh& mesh)
       Point_2 p2 = fit->vertex(2)->point();
       const double x = (p0[0] + p1[0] + p2[0]) / 3;
       const double y = (p0[1] + p1[1] + p2[1]) / 3;
+
       list_of_seeds.push_back(Point_2(x, y));
     }
   }
+
   mesher.set_seeds(list_of_seeds.begin(), list_of_seeds.end(), true);
 
   // Set shape and size criteria
   const int mesh_resolution = parameters["mesh_resolution"];
   if (mesh_resolution > 0)
   {
-    cout << "Mesh resolution set" << endl;
-
-    std::vector<Nef_point_2> points;
-    for (Vertex_const_iterator it = explorer.vertices_begin();
-         it != explorer.vertices_end();
-         it++)
-      points.push_back(it->point());
+    const double min_radius = total_domain.compute_boundingcircle_radius();
+    const double cell_size = 2.0*min_radius/mesh_resolution;
 
-    Min_circle min_circle (points.begin(),
-                           points.end(),
-                           true); //randomize point order
-
-    const double cell_size
-      = 2.0*sqrt(CGAL::to_double(min_circle.circle().squared_radius()))/mesh_resolution;
 
     Mesh_criteria_2 criteria(parameters["triangle_shape_bound"],
                              cell_size);
     mesher.set_criteria(criteria);
-  }
+  } 
   else
   {
     // Set shape and size criteria
@@ -453,10 +446,12 @@ void CSGCGALMeshGenerator2D::generate(Mesh& mesh)
   // Make sure triangulation is valid
   dolfin_assert(cdt.is_valid());
 
+  // Mark the subdomains
+  explore_subdomains(cdt, total_domain, subdomain_geometries);
+
   // Clear mesh
   mesh.clear();
 
-  // Get various dimensions
   const std::size_t gdim = cdt.finite_vertices_begin()->point().dimension();
   const std::size_t tdim = cdt.dimension();
   const std::size_t num_vertices = cdt.number_of_vertices();
@@ -464,7 +459,7 @@ void CSGCGALMeshGenerator2D::generate(Mesh& mesh)
   // Count valid cells
   std::size_t num_cells = 0;
   CDT::Finite_faces_iterator cgal_cell;
-  for (cgal_cell = cdt.finite_faces_begin();
+  for (cgal_cell = cdt.finite_faces_begin(); 
        cgal_cell != cdt.finite_faces_end(); ++cgal_cell)
   {
     // Add cell if it is in the domain
@@ -490,8 +485,6 @@ void CSGCGALMeshGenerator2D::generate(Mesh& mesh)
     Point p;
     p[0] = cgal_vertex->point()[0];
     p[1] = cgal_vertex->point()[1];
-    if (gdim == 3)
-      p[2] = cgal_vertex->point()[2];
 
     // Add mesh vertex
     mesh_editor.add_vertex(vertex_index, p);
@@ -499,30 +492,30 @@ void CSGCGALMeshGenerator2D::generate(Mesh& mesh)
     // Attach index to vertex and increment
     cgal_vertex->info() = vertex_index++;
   }
+
   dolfin_assert(vertex_index == num_vertices);
 
-  // Add cells to mesh
+  // Add cells to mesh and build domain marker mesh function
+  MeshDomains &domain_markers = mesh.domains();
   std::size_t cell_index = 0;
-  for (cgal_cell = cdt.finite_faces_begin();
-       cgal_cell != cdt.finite_faces_end(); ++cgal_cell)
+  for (cgal_cell = cdt.finite_faces_begin(); cgal_cell != cdt.finite_faces_end(); ++cgal_cell)
   {
     // Add cell if it is in the domain
     if (cgal_cell->is_in_domain())
     {
-      mesh_editor.add_cell(cell_index++,
+      mesh_editor.add_cell(cell_index,
                            cgal_cell->vertex(0)->info(),
                            cgal_cell->vertex(1)->info(),
                            cgal_cell->vertex(2)->info());
+
+      domain_markers.set_marker(std::make_pair(cell_index, cgal_cell->counter()), 2);
+      ++cell_index;
     }
   }
   dolfin_assert(cell_index == num_cells);
 
   // Close mesh editor
   mesh_editor.close();
-
-  // Build DOLFIN mesh from CGAL triangulation
-  // FIXME: Why does this not work correctly?
-  //CGALMeshBuilder::build(mesh, cdt);
 }
 
 #else
diff --git a/dolfin/generation/CSGCGALMeshGenerator2D.h b/dolfin/generation/CSGCGALMeshGenerator2D.h
index 7845f2a..f9ed547 100644
--- a/dolfin/generation/CSGCGALMeshGenerator2D.h
+++ b/dolfin/generation/CSGCGALMeshGenerator2D.h
@@ -18,7 +18,7 @@
 // Modified by Johannes Ring, 2012
 //
 // First added:  2012-05-10
-// Last changed: 2013-03-15
+// Last changed: 2013-04-05
 
 #ifndef __CSG_CGAL_MESH_GENERATOR2D_H
 #define __CSG_CGAL_MESH_GENERATOR2D_H
@@ -40,6 +40,7 @@ namespace dolfin
   public :
 
     CSGCGALMeshGenerator2D(const CSGGeometry& geometry);
+    //CSGCGALMeshGenerator2D(const std::vector<boost::shared_ptr<const CSGGeometry> >& subdomains);
 
     ~CSGCGALMeshGenerator2D();
 
@@ -52,6 +53,9 @@ namespace dolfin
       p.add("mesh_resolution", 64);
       p.add("triangle_shape_bound", 0.125);
       p.add("cell_size", 0.25);
+      
+      // shorter edges in the domain will be collapsed before meshing
+      p.add("edge_minimum", 10e-5);
 
       return p;
     }
@@ -59,7 +63,8 @@ namespace dolfin
   private:
 
     #ifdef HAS_CGAL
-    const CSGGeometry& _geometry;
+    //std::vector<boost::shared_ptr<const CSGGeometry> > subdomains;
+    const CSGGeometry &geometry;
     #endif
 
   };
diff --git a/dolfin/generation/CSGGeometry.cpp b/dolfin/generation/CSGGeometry.cpp
index 9b54812..3fb4230 100644
--- a/dolfin/generation/CSGGeometry.cpp
+++ b/dolfin/generation/CSGGeometry.cpp
@@ -15,10 +15,13 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
+// Modified by Benjamin Kehlet, 2013
+//
 // First added:  2012-04-11
-// Last changed: 2012-04-13
+// Last changed: 2013-04-18
 
 #include "CSGGeometry.h"
+#include <dolfin/common/NoDeleter.h>
 
 using namespace dolfin;
 
@@ -33,3 +36,34 @@ CSGGeometry::~CSGGeometry()
   // Do nothing
 }
 //-----------------------------------------------------------------------------
+void CSGGeometry::set_subdomain(std::size_t i, boost::shared_ptr<CSGGeometry> s)
+{
+  dolfin_assert(dim() == s->dim());
+
+  if (i == 0)
+  {
+    error("Setting reserved CSG subdomain (0)");
+  }
+
+  // Check if i already used
+  std::list<std::pair<std::size_t, boost::shared_ptr<const CSGGeometry> > >::iterator it = subdomains.begin();
+  while (it != subdomains.end())
+  {
+    if (it->first == i)
+    {
+       warning("Double declaration of CSG subdomain with index %u.", i);
+
+       // Remove existing declaration
+       it = subdomains.erase(it);
+    }
+    else
+      ++it;
+  }
+
+  subdomains.push_back(std::make_pair(i, s));
+}
+//-----------------------------------------------------------------------------
+void CSGGeometry::set_subdomain(std::size_t i, CSGGeometry& s)
+{
+  set_subdomain(i, reference_to_no_delete_pointer(s));
+}
diff --git a/dolfin/generation/CSGGeometry.h b/dolfin/generation/CSGGeometry.h
index d4d6981..30a976a 100644
--- a/dolfin/generation/CSGGeometry.h
+++ b/dolfin/generation/CSGGeometry.h
@@ -25,6 +25,9 @@
 #define __CSG_GEOMETRY_H
 
 #include <cstddef>
+#include <vector>
+#include <list>
+#include <boost/shared_ptr.hpp>
 #include <dolfin/common/Variable.h>
 
 namespace dolfin
@@ -49,12 +52,19 @@ namespace dolfin
     /// Informal string representation
     virtual std::string str(bool verbose) const = 0;
 
+    void set_subdomain(std::size_t i, boost::shared_ptr<CSGGeometry> s);
+    void set_subdomain(std::size_t i, CSGGeometry& s);
+
     enum Type { Box, Sphere, Cone, Tetrahedron, Surface3D, Circle, Ellipse, Rectangle, Polygon, Union, Intersection, Difference };
     virtual Type getType() const = 0;
 
     virtual bool is_operator() const = 0;
+
+    std::list<std::pair<std::size_t, boost::shared_ptr<const CSGGeometry> > > subdomains;
   };
 
+  
+
 }
 
 #endif
diff --git a/dolfin/generation/CSGOperators.cpp b/dolfin/generation/CSGOperators.cpp
index a23097d..896ba91 100644
--- a/dolfin/generation/CSGOperators.cpp
+++ b/dolfin/generation/CSGOperators.cpp
@@ -16,9 +16,10 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // Modified by Johannes Ring, 2012
+// Modified by Benjamin Kehlet, 2013
 //
 // First added:  2012-04-13
-// Last changed: 2012-05-03
+// Last changed: 2013-06-24
 
 #include <sstream>
 
@@ -46,12 +47,8 @@ CSGUnion::CSGUnion(boost::shared_ptr<CSGGeometry> g0,
                  "Dimensions of geomestries don't match (%d vs %d)",
                  g0->dim(), g1->dim());
   }
-}
-//-----------------------------------------------------------------------------
-std::size_t CSGUnion::dim() const
-{
-  assert(_g0->dim() == _g1->dim());
-  return _g0->dim();
+
+  dim_ = g0->dim();
 }
 //-----------------------------------------------------------------------------
 std::string CSGUnion::str(bool verbose) const
@@ -95,12 +92,8 @@ CSGDifference::CSGDifference(boost::shared_ptr<CSGGeometry> g0,
                  "Dimensions of geomestries don't match (%d vs %d)",
                  g0->dim(), g1->dim());
   }
-}
-//-----------------------------------------------------------------------------
-std::size_t CSGDifference::dim() const
-{
-  assert(_g0->dim() == _g1->dim());
-  return _g0->dim();
+
+  dim_ = g0->dim();
 }
 //-----------------------------------------------------------------------------
 std::string CSGDifference::str(bool verbose) const
@@ -144,12 +137,8 @@ CSGIntersection::CSGIntersection(boost::shared_ptr<CSGGeometry> g0,
                  "Dimensions of geomestries don't match (%d vs %d)",
                  g0->dim(), g1->dim());
   }
-}
-//-----------------------------------------------------------------------------
-std::size_t CSGIntersection::dim() const
-{
-  assert(_g0->dim() == _g1->dim());
-  return _g0->dim();
+
+  dim_ = g0->dim();
 }
 //-----------------------------------------------------------------------------
 std::string CSGIntersection::str(bool verbose) const
diff --git a/dolfin/generation/CSGOperators.h b/dolfin/generation/CSGOperators.h
index 2ada53f..8645d30 100644
--- a/dolfin/generation/CSGOperators.h
+++ b/dolfin/generation/CSGOperators.h
@@ -15,10 +15,10 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// Modified by Benjamin Kehlet, 2012
+// Modified by Benjamin Kehlet, 2012-2013
 //
 // First added:  2012-04-13
-// Last changed: 2012-11-05
+// Last changed: 2013-06-24
 
 #ifndef __CSG_OPERATORS_H
 #define __CSG_OPERATORS_H
@@ -36,6 +36,10 @@ namespace dolfin
   {
    public:
     virtual bool is_operator() const { return true; }
+    std::size_t dim() const { return dim_;}
+
+   protected :
+    std::size_t dim_;
   };
 
   /// Union of CSG geometries
@@ -47,9 +51,6 @@ namespace dolfin
     CSGUnion(boost::shared_ptr<CSGGeometry> g0,
              boost::shared_ptr<CSGGeometry> g1);
 
-    /// Return dimension of geometry
-    std::size_t dim() const;
-
     /// Informal string representation
     std::string str(bool verbose) const;
 
@@ -69,9 +70,6 @@ namespace dolfin
     CSGDifference(boost::shared_ptr<CSGGeometry> g0,
              boost::shared_ptr<CSGGeometry> g1);
 
-    /// Return dimension of geometry
-    std::size_t dim() const;
-
     /// Informal string representation
     std::string str(bool verbose) const;
 
@@ -92,9 +90,6 @@ namespace dolfin
     CSGIntersection(boost::shared_ptr<CSGGeometry> g0,
                     boost::shared_ptr<CSGGeometry> g1);
 
-    /// Return dimension of geometry
-    std::size_t dim() const;
-
     /// Informal string representation
     std::string str(bool verbose) const;
 
diff --git a/dolfin/generation/CSGPrimitive.h b/dolfin/generation/CSGPrimitive.h
index 0dc81d2..3b02024 100644
--- a/dolfin/generation/CSGPrimitive.h
+++ b/dolfin/generation/CSGPrimitive.h
@@ -15,10 +15,10 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// Modified by Benjamin Kehlet, 2012
+// Modified by Benjamin Kehlet, 2012-2013
 //
 // First added:  2012-04-11
-// Last changed: 2012-11-05
+// Last changed: 2013-06-24
 
 #ifndef __CSG_PRIMITIVE_H
 #define __CSG_PRIMITIVE_H
@@ -34,6 +34,7 @@ namespace dolfin
   {
   public:
     virtual bool is_operator() const { return false; }
+    virtual std::size_t dim() const = 0;
   };
 
 }
diff --git a/dolfin/generation/CSGPrimitives2D.h b/dolfin/generation/CSGPrimitives2D.h
index e5af011..1e79e49 100644
--- a/dolfin/generation/CSGPrimitives2D.h
+++ b/dolfin/generation/CSGPrimitives2D.h
@@ -151,10 +151,10 @@ namespace dolfin
     Type getType() const { return CSGGeometry::Rectangle; }
 
     /// Return first corner
-    Point first_corner() const { return Point(_x0, _y0); }
+    Point first_corner() const { return Point(_x0, _x1); }
 
     /// Return second corner
-    Point second_corner() const { return Point(_x1, _y1); }
+    Point second_corner() const { return Point(_y0, _y1); }
 
   private: