예제 #1
0
void MyWindow::perform_mink_sum()
{
  if (red_set.number_of_polygons_with_holes() > 1 ||
     blue_set.number_of_polygons_with_holes() > 1)
    {
      mink_sum_warning();
      return;
    }

  Polygon_with_holes red_p_wh;
  CGAL::Oneset_iterator<Polygon_with_holes> oi1(red_p_wh);
  red_set.polygons_with_holes(oi1);
  if (red_p_wh.has_holes() || red_p_wh.is_unbounded())
    {
      mink_sum_warning();
      return;
    }
  const Polygon_2& red_p = red_p_wh.outer_boundary();

  Polygon_with_holes blue_p_wh;
  CGAL::Oneset_iterator<Polygon_with_holes> oi2(blue_p_wh);
  blue_set.polygons_with_holes(oi2);
  if (blue_p_wh.has_holes() || blue_p_wh.is_unbounded())
    {
      mink_sum_warning();
      return;
    }
  QCursor old = widget->cursor();
  widget->setCursor(Qt::WaitCursor);
  const Polygon_2& blue_p = blue_p_wh.outer_boundary();
  if (is_linear(red_p) && is_linear(blue_p))
    {
      const Linear_polygon_2& linear_red_p  = circ_2_linear(red_p);
      const Linear_polygon_2& linear_blue_p = circ_2_linear(blue_p);

      const Linear_polygon_with_holes_2& res_p =
        CGAL::minkowski_sum_2(linear_red_p, linear_blue_p);

      Polygon_with_holes res_p_wh  = linear_2_circ(res_p);
      res_set.clear();
      res_set.insert(res_p_wh);
      newtoolbar->reset();
      std::list<Polygon_with_holes> res_pgns;
      res_pgns.push_back(res_p_wh);
      draw_result(res_pgns.begin(), res_pgns.end());
      widget->setCursor(old);
    }
  else if (is_disc(red_p) && is_linear(blue_p))
    {
      const Linear_polygon_2& linear_blue_p = circ_2_linear(blue_p);
      const Polygon_with_holes& res_p_wh =
        CGAL::approximated_offset_2 (linear_blue_p, get_radius(red_p), 0.00001);

      res_set.clear();
      res_set.insert(res_p_wh);
      newtoolbar->reset();
      std::list<Polygon_with_holes> res_pgns;
      res_pgns.push_back(res_p_wh);
      draw_result(res_pgns.begin(), res_pgns.end());
      widget->setCursor(old);
    }
  else if (is_disc(blue_p) && is_linear(red_p))
    {
      const Linear_polygon_2& linear_red_p = circ_2_linear(red_p);
      const Polygon_with_holes& res_p_wh =
        CGAL::approximated_offset_2 (linear_red_p, get_radius(blue_p), 0.00001);

      res_set.clear();
      res_set.insert(res_p_wh);
      newtoolbar->reset();
      std::list<Polygon_with_holes> res_pgns;
      res_pgns.push_back(res_p_wh);
      draw_result(res_pgns.begin(), res_pgns.end());
      widget->setCursor(old);
    } 
  else
    {
      mink_sum_warning();
      widget->setCursor(old);
      return;
    }
}
예제 #2
0
  void Refinement :: MakeSecondOrder (Mesh & mesh)
  {
    int nseg, nse, ne;

    mesh.ComputeNVertices();
    mesh.SetNP(mesh.GetNV());
  
    INDEX_2_HASHTABLE<int> between(mesh.GetNP() + 5);


    bool thinlayers = 0;
    for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
      if (mesh[ei].GetType() == PRISM ||
	  mesh[ei].GetType() == PRISM12)
	thinlayers = 1;
    

    nseg = mesh.GetNSeg();
    for (SegmentIndex si = 0; si < nseg; si++)
      {
	Segment & el = mesh.LineSegment(si);

	INDEX_2 i2 = INDEX_2::Sort (el[0], el[1]);

	if (between.Used(i2))
	  el[2] = between.Get(i2);
	else
	  {
	    Point<3> pb;
	    EdgePointGeomInfo ngi;
            PointBetween (mesh.Point (el[0]),
                          mesh.Point (el[1]), 0.5,
			  el.surfnr1, el.surfnr2,
			  el.epgeominfo[0], el.epgeominfo[1],
			  pb, ngi);
	  
	    el[2] = mesh.AddPoint (pb, mesh.Point(el[0]).GetLayer(), 
				   EDGEPOINT);
	    between.Set (i2, el[2]);
	  }
      }

    // refine surface elements
    nse = mesh.GetNSE();
    for (SurfaceElementIndex sei = 0; sei < nse; sei++)
      {
	int j;
	const Element2d & el = mesh.SurfaceElement(sei);

	int onp(0);
      
	Element2d newel;
	newel.SetIndex (el.GetIndex());

	static int betw_trig[3][3] =
	  { { 1, 2, 3 },
	    { 0, 2, 4 },
	    { 0, 1, 5 } };
	static int betw_quad6[2][3] =
	  { { 0, 1, 4 },
	    { 3, 2, 5 } };
	static int betw_quad8[4][3] =
	  { { 0, 1, 4 },
	    { 3, 2, 5 },
	    { 0, 3, 6 },
	    { 1, 2, 7 } };
	int (*betw)[3] = NULL;
      
	switch (el.GetType())
	  {
	  case TRIG:
	  case TRIG6:
	    {
	      betw = betw_trig;
	      newel.SetType (TRIG6);
	      onp = 3;
	      break;
	    }
	  case QUAD:
	  case QUAD6: 
	  case QUAD8:
	    {
	      if (thinlayers)
		{
		  betw = betw_quad6;
		  newel.SetType (QUAD6);
		}
	      else
		{
		  betw = betw_quad8;
		  newel.SetType (QUAD8);
		}
	      onp = 4;
	      break;
	    }
	  default:
	    PrintSysError ("Unhandled element in secondorder:", int(el.GetType()));
	  }

	for (j = 0; j < onp; j++)
	  newel[j] = el[j];
      
	int nnp = newel.GetNP();
	for (j = 0; j < nnp-onp; j++)
	  {
	    int pi1 = newel[betw[j][0]];
	    int pi2 = newel[betw[j][1]];
	  
	    INDEX_2 i2 = INDEX_2::Sort (pi1, pi2);
	  
	    if (between.Used(i2))
	      newel[onp+j] = between.Get(i2);
	    else
	      {
		Point<3> pb;
		PointGeomInfo newgi;
		PointBetween (mesh.Point (pi1),
			      mesh.Point (pi2), 0.5, 
			      mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(),
			      el.GeomInfoPi (betw[j][0]+1),
			      el.GeomInfoPi (betw[j][1]+1),
			      pb, newgi);

		newel[onp+j] = mesh.AddPoint (pb, mesh.Point(pi1).GetLayer(), 
					      SURFACEPOINT);
		between.Set (i2, newel[onp+j]);
	      }
	  }
      
	mesh.SurfaceElement(sei) = newel;
      }

 
    //    int i, j;



    // refine volume elements
    ne = mesh.GetNE();
    for (int i = 1; i <= ne; i++)
      {
	const Element & el = mesh.VolumeElement(i);
	int onp = 0;

	Element newel;
	newel.SetIndex (el.GetIndex());

	static int betw_tet[6][3] =
	  { { 0, 1, 4 },
	    { 0, 2, 5 },
	    { 0, 3, 6 },
	    { 1, 2, 7 },
	    { 1, 3, 8 },
	    { 2, 3, 9 } };
	static int betw_prism[6][3] =
	  {
	    { 0, 2, 6 },
	    { 0, 1, 7 },
	    { 1, 2, 8 },
	    { 3, 5, 9 },
	    { 3, 4, 10 },
	    { 4, 5, 11 },
	  };
	int (*betw)[3] = NULL;

	switch (el.GetType())
	  {
	  case TET:
	  case TET10:
	    {
	      betw = betw_tet;
	      newel.SetType (TET10);
	      onp = 4;
	      break;
	    }
	  case PRISM:
	  case PRISM12:
	    {
	      betw = betw_prism;
	      newel.SetType (PRISM12);
	      onp = 6;
	      break;
	    }
	  default:
	    PrintSysError ("MakeSecondOrder, illegal vol type ", el.GetType());
	  }


	for (int j = 1; j <= onp; j++)
	  newel.PNum(j) = el.PNum(j);
	int nnp = newel.GetNP();

	for (int j = 0; j < nnp-onp; j++)
	  {
	    INDEX_2 i2(newel[betw[j][0]],
		       newel[betw[j][1]]);
	    i2.Sort();
	  
	    if (between.Used(i2))
	      newel.PNum(onp+1+j) = between.Get(i2);
	    else
	      {
		newel.PNum(onp+1+j) = mesh.AddPoint
		  (Center (mesh.Point(i2.I1()),
			   mesh.Point(i2.I2())),
		   mesh.Point(i2.I1()).GetLayer(), 
		   INNERPOINT);

		between.Set (i2, newel.PNum(onp+1+j));
	      }
	  }

	mesh.VolumeElement (i) = newel;
      }


    // makes problems after linear mesh refinement, since
    // 2nd order identifications are not removed
    // update identification tables
    for (int i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++)
      {
	Array<int,PointIndex::BASE> identmap;
	mesh.GetIdentifications().GetMap (i, identmap);

	for (INDEX_2_HASHTABLE<int>::Iterator it = between.Begin();
	     it != between.End(); it++)
	  {
	      INDEX_2 i2;
	      int newpi;
	      between.GetData (it, i2, newpi);
	      INDEX_2 oi2(identmap.Get(i2.I1()),
			  identmap.Get(i2.I2()));
	      oi2.Sort();
	      if (between.Used (oi2))
		{
		  int onewpi = between.Get(oi2);
		  mesh.GetIdentifications().Add (newpi, onewpi, i);
		}
	  }

	/*
	for (int j = 1; j <= between.GetNBags(); j++)
	  for (int k = 1; k <= between.GetBagSize(j); k++)
	    {
	      INDEX_2 i2;
	      int newpi;
	      between.GetData (j, k, i2, newpi);
	      INDEX_2 oi2(identmap.Get(i2.I1()),
			  identmap.Get(i2.I2()));
	      oi2.Sort();
	      if (between.Used (oi2))
		{
		  int onewpi = between.Get(oi2);
		  mesh.GetIdentifications().Add (newpi, onewpi, i);
		}
	    }
	*/
      }


    //  mesh.mglevels++;
    int oldsize = mesh.mlbetweennodes.Size();
    mesh.mlbetweennodes.SetSize(mesh.GetNP());
    for (int i = oldsize; i < mesh.GetNP(); i++)
      mesh.mlbetweennodes[i] = INDEX_2(0,0);

    /*
    for (i = 1; i <= between.GetNBags(); i++)
      for (j = 1; j <= between.GetBagSize(i); j++)
	{
	  INDEX_2 oldp;
	  int newp;
	  between.GetData (i, j, oldp, newp);
	  mesh.mlbetweennodes.Elem(newp) = oldp;
	}
    */

    for (INDEX_2_HASHTABLE<int>::Iterator it = between.Begin();
	 it != between.End(); it++)
      {
	mesh.mlbetweennodes[between.GetData (it)] = between.GetHash(it);
      }

    mesh.ComputeNVertices();
    mesh.RebuildSurfaceElementLists();
    //  ValidateSecondOrder (mesh);
  }