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; } }
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); }