本文整理汇总了C++中Halfedge_handle::opposite方法的典型用法代码示例。如果您正苦于以下问题:C++ Halfedge_handle::opposite方法的具体用法?C++ Halfedge_handle::opposite怎么用?C++ Halfedge_handle::opposite使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Halfedge_handle
的用法示例。
在下文中一共展示了Halfedge_handle::opposite方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: h
// Dessine la couronne intérieure
std::vector<Point_3> DegradeAnObject::drawInsideImpactOnFacet(std::vector<Point_3> points, std::vector<Halfedge_handle> hhs, Facet f, int index) {
std::vector<Point_3> pts;
for(int i = 0 ; i < points.size() ; i++) {
int j;
if(i == points.size()-1) {
j = 0;
}
else {
j = i+1;
}
Vector_3 h(hhs[i]->opposite()->vertex()->point(), hhs[i]->vertex()->point());
Vector_3 g(hhs[j]->opposite()->vertex()->point(), hhs[j]->vertex()->point());
Vector_3 norm = getNormalOfFacet(f);
Vector_3 rh = normalizeVector(rotationVector(h, norm, M_PI/2));
Vector_3 rg = normalizeVector(rotationVector(g, norm, M_PI/2));
Vector_3 comb = 0.01*normalizeVector(rh+rg);
Point_3 newPoint = hhs[i]->vertex()->point() + comb;
Halfedge_handle hh = polys[index].split_vertex(hhs[j]->opposite(), hhs[i]);
hh->vertex()->point() = newPoint;
polys[index].split_facet(hh->opposite()->next()->next(), hh->opposite());
polys[index].split_facet(hh->next()->next(), hh);
pts.push_back(newPoint);
}
return pts;
}
示例2: Check_Manifold_Property
//Description :: Check if removal of this vertex would violate the manifold_property or not.
bool Check_Manifold_Property(Halfedge_handle h, const int &type,const int &valence)
{
bool check = false;
Halfedge_handle g = h;
int* Points_index = new int[valence];
// if valence is 3, no new edge is inserted, so always safe to remove.
if(valence == 3)
{
return false;
}
else
{
// Points_index[] contains all boundary vertices' indices (ordered in counterclockwise)
Points_index[0] = g->vertex()->Vertex_Number_S;
g = g->next(); // g points center vertex;
for(int i=1; i<valence; i++)
{
g = g->prev_on_vertex();// around the vertex in the counterclockwise way.
Points_index[i] = g->opposite()->vertex()->Vertex_Number_S;
}
// quadrangle
if (valence == 4)
{
if ((type == 5) || (type == 8))
{
g = h->opposite();
Halfedge_around_vertex_circulator Hvc = g->vertex_begin();
Halfedge_around_vertex_circulator Hvc_end = Hvc;
CGAL_For_all(Hvc,Hvc_end)
{
if (Hvc->opposite()->vertex()->Vertex_Number_S == Points_index[1])
check = true;
}
}
else if (( type == 6) || (type == 7))
{
g = h;
Halfedge_around_vertex_circulator Hvc = g->vertex_begin();
Halfedge_around_vertex_circulator Hvc_end = Hvc;
CGAL_For_all(Hvc,Hvc_end)
{
if (Hvc->opposite()->vertex()->Vertex_Number_S == Points_index[2])
check = true;;
}
}
示例3: Point
typename Poly::Halfedge_handle make_cube_3( Poly& P) {
// appends a cube of size [0,1]^3 to the polyhedron P.
CGAL_precondition( P.is_valid());
typedef typename Poly::Point_3 Point;
typedef typename Poly::Plane_3 Plane;
typedef typename Poly::Halfedge_handle Halfedge_handle;
Halfedge_handle h = P.make_tetrahedron( Point( 1, 0, 0),
Point( 0, 0, 1),
Point( 0, 0, 0),
Point( 0, 1, 0));
Halfedge_handle g = h->next()->opposite()->next();
P.split_edge( h->next());
P.split_edge( g->next());
P.split_edge( g);
h->next()->vertex()->point() = Point( 1, 0, 1);
g->next()->vertex()->point() = Point( 0, 1, 1);
g->opposite()->vertex()->point() = Point( 1, 1, 0);
Halfedge_handle f = P.split_facet( g->next(), g->next()->next()->next());
Halfedge_handle e = P.split_edge( f);
e->vertex()->point() = Point( 1, 1, 1);
P.split_facet( e, f->next()->next());
CGAL_postcondition( P.is_valid());
g = h;
g->facet()->plane() = Plane( g->vertex()->point(),
g->next()->vertex()->point(),
g->next()->next()->vertex()->point());
g = h->opposite();
g->facet()->plane() = Plane( g->vertex()->point(),
g->next()->vertex()->point(),
g->next()->next()->vertex()->point());
g = h->next()->opposite();
g->facet()->plane() = Plane( g->vertex()->point(),
g->next()->vertex()->point(),
g->next()->next()->vertex()->point());
g = h->next()->next()->opposite();
g->facet()->plane() = Plane( g->vertex()->point(),
g->next()->vertex()->point(),
g->next()->next()->vertex()->point());
g = h->next()->next()->next()->opposite();
g->facet()->plane() = Plane( g->vertex()->point(),
g->next()->vertex()->point(),
g->next()->next()->vertex()->point());
g = g->next()->next()->opposite();
g->facet()->plane() = Plane( g->vertex()->point(),
g->next()->vertex()->point(),
g->next()->next()->vertex()->point());
return h;
}
示例4: getExteriorHalfedge
// Recherche les halfedges des - facets du point - qui ne contiennent pas le point
Halfedge_handle DegradeAnObject::getExteriorHalfedge(Point_3 p, Segment_3 s, std::vector<Facet> fcts) {
Halfedge_handle retHh;
for(int i = 0 ; i < fcts.size() ; i++) {
Halfedge_handle hh = fcts[i].halfedge();
for(int j = 0 ; j < 3 ; j++) {
if(hh->vertex()->point() != p && hh->opposite()->vertex()->point() != p) {
Segment_3 seg(hh->opposite()->vertex()->point(), hh->vertex()->point());
if(!seg.is_degenerate()) {
if(CGAL::do_intersect(s, seg)) {
retHh = hh;
}
}
}
hh = hh->next();
}
}
return retHh;
}
示例5: Convert
void Convert ( OffSurface_mesh& off, char const* gts_name )
{
std::ofstream gts(gts_name);
if ( gts )
{
std::cout << "Writting " << gts_name << std::endl ;
gts << off.size_of_vertices() << " " << (off.size_of_halfedges()/2) << " " << off.size_of_facets() << std::endl ;
int vid = 1 ;
for ( Vertex_iterator vit = off.vertices_begin() ; vit != off.vertices_end() ; ++ vit )
{
Vertex_handle v = vit ;
gts << v->point().x() << " " << v->point().y() << " " << v->point().z() << std::endl ;
v->id() = vid ++ ;
}
int eid = 1 ;
for ( Edge_iterator eit = off.edges_begin(); eit != off.edges_end() ; ++ eit )
{
Halfedge_handle e = eit ;
Vertex_handle s = e->opposite()->vertex();
Vertex_handle t = e->vertex();
gts << s->id() << " " << t->id() << std::endl ;
e ->id() = eid ;
e->opposite()->id() = eid ;
++ eid ;
}
for ( Facet_iterator fit = off.facets_begin(); fit != off.facets_end() ; ++ fit )
{
Facet_handle f = fit ;
Halfedge_handle e0 = f->halfedge();
Halfedge_handle e1 = e0->next();
Halfedge_handle e2 = e1->next();
gts << e0->id() << " " << e1->id() << " " << e2->id() << std::endl ;
}
}
else std::cerr << "Unable to open output file: " << gts_name << std::endl ;
}
示例6: trisect_border_halfedge
void trisect_border_halfedge( Polyhedron& P, Halfedge_handle e) {
CGAL_precondition( e->is_border());
// Create two new vertices on e.
e = e->prev();
P.split_vertex( e, e->next()->opposite());
P.split_vertex( e, e->next()->opposite());
e = e->next();
// We use later for the smoothing step that e->next()->next()
// is our original halfedge we started with, i.e., its vertex is
// from the unrefined mesh. Split the face twice.
Halfedge_handle h = e->opposite()->next();
P.split_facet( e->next()->next()->opposite(), h);
P.split_facet( e->next()->opposite(), h);
}
示例7: addAndJoinNewPoint
Halfedge_handle DegradeAnObject::addAndJoinNewPoint(Point_3 p, Halfedge_handle previousHalfedge, Halfedge_handle hh, Segment_3 s, int index) {
Point_3 intersect;
Halfedge_handle splittedHalfedge;
Segment_3 seg(hh->opposite()->vertex()->point(), hh->vertex()->point());
Point_3* chkPt;
CGAL::cpp11::result_of<Kernel::Intersect_3(Segment_3, Segment_3)>::type result = CGAL::intersection(s, seg);
if (result) {
chkPt = boost::get<Point_3 >(&*result);
intersect = *chkPt;
}
Halfedge_handle split = splitEdge(hh, intersect, index);
Halfedge_handle hhx = polys[index].split_facet(previousHalfedge, split);
Halfedge_handle oppositePoint = hhx->next()->opposite();
polys[index].split_facet(oppositePoint, oppositePoint->next()->next());
return oppositePoint;
}
示例8: gnuplot_print_faces_2
void gnuplot_print_faces_2(std::ostream& out,
CGAL::Straight_skeleton_2<Kernel>::Face_iterator faces_begin,
CGAL::Straight_skeleton_2<Kernel>::Face_iterator faces_end)
{
typedef CGAL::Straight_skeleton_2<Kernel> Ss;
typedef Ss::Face_iterator Face_iterator;
typedef Ss::Halfedge_handle Halfedge_handle;
typedef Ss::Vertex_handle Vertex_handle;
for (Face_iterator fi = faces_begin; fi != faces_end; ++fi)
{
Halfedge_handle halfedge = fi->halfedge();
Halfedge_handle first = halfedge;
do
{
Vertex_handle s = halfedge->opposite()->vertex();
Vertex_handle t = halfedge->vertex();
const Point_2& sp(s->point());
const Point_2& tp(t->point());
sp.insert(out) << endl;
tp.insert(out) << endl;
// out << sp << endl;
// out << tp << endl;
out << endl << endl;
// // Add polygon vertices to triangulation
// CDT::Vertex_handle ds = cdt.insert(s->point());
// CDT::Vertex_handle dt = cdt.insert(t->point());
// ds->info() = s->is_contour();
// dt->info() = t->is_contour();
// cdt.insert_constraint(ds, dt);
halfedge = halfedge->next();
} while (halfedge != first);
}
}
示例9: printHalfedge
void printHalfedge( const Halfedge_handle & hh )
{
cerr << setw( 3 ) << hh->opposite()->vertex()->id()
<< " == " << setw( 3 ) << hh->vertex()->id() << endl;
}
示例10: SubdiviserPolyedre
void Boolean_Operations_Component::SubdiviserPolyedre(PolyhedronPtr pMesh)
{
//Each facet must be triangular
if(!pMesh->is_pure_triangle())
{
pMesh->triangulate();
return;
}
Facet_iterator pFacet;
Vector Vcenter;
//Initialization of the tags
for (pFacet = pMesh->facets_begin(); pFacet != pMesh->facets_end(); pFacet++)
{
Halfedge_around_facet_circulator pHEcirc = pFacet->facet_begin();
pFacet->Issub = false;
pHEcirc->Isnew = false;
pHEcirc->vertex()->Isnew = false;
pHEcirc++;
pHEcirc->Isnew = false;
pHEcirc->vertex()->Isnew = false;
pHEcirc++;
pHEcirc->Isnew = false;
pHEcirc->vertex()->Isnew = false;
}
//For each facet of the polyhedron
for (pFacet = pMesh->facets_begin(); pFacet != pMesh->facets_end(); pFacet++)
{
//We subdivide the facet if it is not already done
if(!(pFacet->Issub))
{
Halfedge_handle pHE = pFacet->facet_begin();
for(unsigned int i = 0;i!=5;i++)
{
if(!pHE->Isnew)
{
//each edge is splited in its center
Vcenter = Vector(0.0, 0.0, 0.0);
Vcenter = ( (pHE->vertex()->point() - CGAL::ORIGIN) + (pHE->opposite()->vertex()->point() - CGAL::ORIGIN) ) / 2;
pHE = pMesh->split_edge(pHE);
pHE->vertex()->point() = CGAL::ORIGIN + Vcenter;
//update of the tags (the new vertex and the four new halfedges
pHE->vertex()->Isnew = true;
pHE->Isnew = true;
pHE->opposite()->Isnew = true;
pHE->next()->Isnew = true;
pHE->next()->opposite()->Isnew = true;
}
pHE = pHE->next();
}
//Three new edges are build between the three new vertices, and the tags of the facets are updated
if(!pHE->vertex()->Isnew) pHE = pHE->next();
pHE = pMesh->split_facet(pHE, pHE->next()->next());
pHE->opposite()->facet()->Issub = true;
pHE = pMesh->split_facet(pHE, pHE->next()->next());
pHE->opposite()->facet()->Issub = true;
pHE = pMesh->split_facet(pHE, pHE->next()->next());
pHE->opposite()->facet()->Issub = true;
pHE->facet()->Issub = true;
}
}
}
示例11: Find_Type
// Description : To find a correspondent type to retriangulate.
int Find_Type(const Halfedge_handle &h,const unsigned int &valence)
{
int type = 0;
if (valence == 3)
{
if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS))
type = 1;
else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS))
type = 2;
else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS))
type = 3;
else if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS))
type = 4;
}
else if (valence == 4)
{
if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS))
type = 5;
else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS))
type = 6;
else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS))
type = 7;
else if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS))
type = 8;
}
else if (valence == 5)
{
if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS))
type = 9;
else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS))
type = 10;
else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS))
type = 11;
else if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS))
type = 12;
}
else if (valence == 6)
{
if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS))
type = 13;
else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS))
type = 14;
else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS))
type = 15;
else if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS))
type = 16;
}
return type;
}
示例12: vertexTo
// compute one cross point between 1-ring of c_vh and cutPlane
bool vertexTo(Vertex_handle &c_vh, Halfedge_handle &c_hh, Vertex_handle center,
Halfedge_vertex_circulator &optimal_start_spoke,
const Plane_3 &cutPlane, Polyhedron* mesh, std::list<Point_3> &cross_points,
int nthTarget)
{
bool result(false);
Halfedge_vertex_circulator hc;
if ( c_vh == center )
hc = optimal_start_spoke;
else
hc = c_vh->vertex_begin();
Halfedge_vertex_circulator end = hc;
CGAL_For_all(hc,end)
{
Vertex_handle lvh = hc->opposite()->vertex();
Vertex_handle rvh = hc->next()->vertex();
Point_3 lp = lvh->point();
Point_3 rp = rvh->point();
int il = cutPlane.oriented_side(lp);
int ir = cutPlane.oriented_side(rp);
int tmp = il*ir;
if ( tmp<0)//异侧
{
Halfedge_handle lrhh = hc->next()->next();
if (lrhh->tag()==nthTarget)//在找这次的target的过程中已经用过了
{
continue;
}
else
{
lrhh->tag(nthTarget);
lrhh->opposite()->tag(nthTarget);
}
if ( c_vh == center )
{
optimal_start_spoke = hc;// ++optimal_start_spoke;
}
Point_3 cp = compute_cross_point(cutPlane,lp,rp);
cross_points.push_back(cp);
c_hh = hc->next()->next()->opposite();
c_vh = 0;
result = true;
break;
}
else if(tmp>0)//同侧
{
continue;
}
if (ir)//lp is on the cut plane
{
if (lvh->tag()==nthTarget)//在找这次的target的过程中已经用过了
{
continue;
}
else
{
lvh->tag(nthTarget);
}
if ( c_vh == center)
{
optimal_start_spoke = hc;// ++optimal_start_spoke;
}
c_vh = lvh;
}
else
{
if (rvh->tag()==nthTarget)//在找这次的target的过程中已经用过了
{
continue;
}
else
{
rvh->tag(nthTarget);
}
if ( c_vh == center)
{
optimal_start_spoke = hc; ++optimal_start_spoke; //++optimal_start_spoke;
}
c_vh = rvh;
}
cross_points.push_back(c_vh->point());
c_hh = 0;
result = true;
break;
}
示例13: noTVertice
// Annule les T Vertices sur les faces adjacentes
void DegradeAnObject::noTVertice(Halfedge_handle hh1, Halfedge_handle hh2, Halfedge_handle hh3, int index) {
Halfedge_handle h = polys[index].split_facet(hh1->opposite(), hh1->opposite()->next()->next());
h = polys[index].split_facet(hh2->opposite(), hh2->opposite()->next()->next());
h = polys[index].split_facet(hh3->opposite(), hh3->opposite()->next()->next());
}
示例14: test_HalfedgeDS_decorator
void test_HalfedgeDS_decorator() {
// Simple instantiation of the default halfedge data structure.
typedef CGAL_HALFEDGEDS_DEFAULT<Dummy_traits_2> HDS;
typedef CGAL::HalfedgeDS_decorator<HDS> Decorator;
typedef HDS::Halfedge_handle Halfedge_handle;
typedef HDS::Face_handle Face_handle;
HDS hds;
Decorator decorator(hds);
// Check create single loop.
Halfedge_handle h = decorator.create_loop();
hds.normalize_border();
assert( hds.size_of_vertices() == 1);
assert( hds.size_of_halfedges() == 2);
assert( hds.size_of_faces() == 2);
assert( decorator.is_valid( false, 4));
// Restart with open segment.
hds.clear();
hds.normalize_border();
assert( decorator.is_valid( false, 4));
h = decorator.create_segment();
assert( hds.size_of_vertices() == 2);
assert( hds.size_of_halfedges() == 2);
assert( hds.size_of_faces() == 1);
assert( decorator.is_valid( false, 4));
// Create border edge and check normalization.
decorator.set_face( h->opposite(), Face_handle());
hds.normalize_border();
assert( hds.size_of_border_halfedges() == 1);
assert( hds.size_of_border_edges() == 1);
assert( decorator.normalized_border_is_valid());
decorator.set_face( h->opposite(), h->face());
hds.normalize_border();
assert( hds.size_of_border_halfedges() == 0);
assert( hds.size_of_border_edges() == 0);
assert( decorator.is_valid( false, 4));
// Extend edge to two triangles.
Halfedge_handle g = decorator.split_vertex( h, h);
assert( decorator.is_valid( false, 4));
assert( h != g);
assert( h->next()->next() == g);
assert( h == g->next()->next());
assert( h->opposite() == g->next());
assert( g->opposite() == h->next());
Halfedge_handle g2 = decorator.split_face(h->opposite(),g->opposite());
assert( decorator.is_valid( false, 4));
assert( h->opposite()->next() == g2);
assert( g2->next() == g);
decorator.split_vertex( g2, g->opposite());
assert( decorator.is_valid( false, 4));
assert( g->next()->next()->next()->next() == g);
Halfedge_handle g3 =
decorator.split_face( g2->next()->opposite(), h);
assert( decorator.is_valid( false, 4));
assert( g->next()->next()->next()->next() == g);
assert( h->next()->next()->next() == h);
assert( g3->next()->next()->next() == g3);
assert( g3->next() == g->opposite());
assert( g3->opposite()->next() == g2->opposite());
assert( g3->opposite() == h->next());
// Edge flip within the triangle.
Halfedge_handle g4 = decorator.flip_edge( g3);
assert( decorator.is_valid( false, 4));
assert( g4 == g3);
assert( g3->next()->next() == g2->opposite());
assert( g3->opposite()->next() == h);
assert( g->next()->next()->next()->next() == g);
assert( h->next()->next()->next() == h);
assert( g3->next()->next()->next() == g3);
// Reverse face orientation.
decorator.inside_out();
assert( decorator.is_valid( false, 4));
decorator.inside_out();
assert( decorator.is_valid( false, 4));
// Check hole manipulations.
decorator.make_hole(g);
hds.normalize_border();
assert( hds.size_of_border_halfedges() == 4);
assert( hds.size_of_border_edges() == 4);
assert( decorator.is_valid( false, 4));
// Reverse face orientation, deal also with the hole..
decorator.inside_out();
assert( decorator.is_valid( false, 3));
hds.normalize_border();
assert( decorator.is_valid( false, 4));
// Check add_face_to_border.
hds.clear();
h = decorator.create_loop();
decorator.make_hole( h->opposite());
hds.normalize_border();
assert( decorator.is_valid( false, 4));
decorator.add_face_to_border( h->opposite(), h->opposite());
assert( hds.size_of_halfedges() == 4);
//.........这里部分代码省略.........
示例15: test_HalfedgeDS_decorator2
void test_HalfedgeDS_decorator2() {
// Instantiation of the halfedge data structure using vector
// with max-bases for a polyhedral surface.
typedef CGAL::HalfedgeDS_vector< Dummy_traits_3,
CGAL::Polyhedron_items_3> HDS;
typedef CGAL::HalfedgeDS_decorator<HDS> Decorator;
typedef HDS::Halfedge_handle Halfedge_handle;
typedef HDS::Face_handle Face_handle;
HDS hds(4,10,3);
Decorator decorator(hds);
// Check create single loop.
Halfedge_handle h = decorator.create_loop();
hds.normalize_border();
assert( hds.size_of_vertices() == 1);
assert( hds.size_of_halfedges() == 2);
assert( hds.size_of_faces() == 2);
assert( decorator.is_valid( false, 4));
// Restart with open segment.
hds.clear();
hds.normalize_border();
assert( decorator.is_valid( false, 4));
h = decorator.create_segment();
assert( hds.size_of_vertices() == 2);
assert( hds.size_of_halfedges() == 2);
assert( hds.size_of_faces() == 1);
assert( decorator.is_valid( false, 3));
hds.normalize_border();
assert( decorator.is_valid( false, 4));
// Create border edge and check normalization.
decorator.set_face( h->opposite(), Face_handle());
hds.normalize_border();
assert( hds.size_of_border_halfedges() == 1);
assert( hds.size_of_border_edges() == 1);
assert( decorator.normalized_border_is_valid());
decorator.set_face( h->opposite(), h->face());
hds.normalize_border();
assert( hds.size_of_border_halfedges() == 0);
assert( hds.size_of_border_edges() == 0);
assert( decorator.is_valid( false, 4));
// Extend edge to two triangles.
Halfedge_handle g = decorator.split_vertex( h, h);
assert( decorator.is_valid( false, 3));
hds.normalize_border();
assert( decorator.is_valid( false, 4));
assert( h != g);
assert( h->next()->next() == g);
assert( h == g->next()->next());
assert( h->opposite() == g->next());
assert( g->opposite() == h->next());
Halfedge_handle g2 = decorator.split_face(h->opposite(),g->opposite());
hds.normalize_border();
assert( decorator.is_valid( false, 4));
assert( h->opposite()->next() == g2);
assert( g2->next() == g);
decorator.split_vertex( g2, g->opposite());
assert( decorator.is_valid( false, 3));
hds.normalize_border();
assert( decorator.is_valid( false, 4));
assert( g->next()->next()->next()->next() == g);
Halfedge_handle g3 =
decorator.split_face( g2->next()->opposite(), h);
hds.normalize_border();
assert( decorator.is_valid( false, 4));
assert( g->next()->next()->next()->next() == g);
assert( h->next()->next()->next() == h);
assert( g3->next()->next()->next() == g3);
assert( g3->next() == g->opposite());
assert( g3->opposite()->next() == g2->opposite());
assert( g3->opposite() == h->next());
// Edge flip within the triangle.
Halfedge_handle g4 = decorator.flip_edge( g3);
assert( decorator.is_valid( false, 3));
hds.normalize_border();
assert( decorator.is_valid( false, 4));
assert( g4 == g3);
assert( g3->next()->next() == g2->opposite());
assert( g3->opposite()->next() == h);
assert( g->next()->next()->next()->next() == g);
assert( h->next()->next()->next() == h);
assert( g3->next()->next()->next() == g3);
// Reverse face orientation.
decorator.inside_out();
assert( decorator.is_valid( false, 4));
}