mirror of https://github.com/CGAL/cgal
Add a function that exports the facets of a c2t3 in a facegraph.
This commit is contained in:
parent
fafc89222f
commit
a2fa153afe
|
|
@ -0,0 +1,159 @@
|
||||||
|
// Copyright (c) 2007-09 INRIA Sophia-Antipolis (France).
|
||||||
|
// Copyright (c) 2017 GeometryFactory (France).
|
||||||
|
|
||||||
|
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
// Author(s) : Maxime Gimeno, Pierre Alliez
|
||||||
|
#ifndef CGAL_OUTPUT_SURFACE_FACETS_TO_FACEGRAPH_H
|
||||||
|
#define CGAL_OUTPUT_SURFACE_FACETS_TO_FACEGRAPH_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Surface_mesher.h>
|
||||||
|
|
||||||
|
//! Gets reconstructed surface out of a SurfaceMeshComplex_2InTriangulation_3 object.
|
||||||
|
//!
|
||||||
|
//! This variant exports the surface as a FaceGraph and appends it to `graph`.
|
||||||
|
//! It requires the surface to be manifold. For this purpose,
|
||||||
|
//! you may call make_surface_mesh() with Manifold_tag or Manifold_with_boundary_tag parameter.
|
||||||
|
//!
|
||||||
|
//! @tparam C2T3 model of the SurfaceMeshComplex_2InTriangulation_3 concept.
|
||||||
|
//! @tparam FaceGraph a model of FaceGraph.
|
||||||
|
//!
|
||||||
|
//! @param c2t3 an instance of a manifold C2T3.
|
||||||
|
//! @param graph an instance of FaceGraph.
|
||||||
|
template<class C2T3, class FaceGraph>
|
||||||
|
void c2t3_to_facegraph(const C2T3& c2t3, FaceGraph& graph)
|
||||||
|
{
|
||||||
|
typedef typename boost::property_map<FaceGraph, boost::vertex_point_t>::type VertexPointMap;
|
||||||
|
typedef typename C2T3::Triangulation Tr;
|
||||||
|
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||||
|
typedef typename Tr::Vertex_iterator Vertex_iterator;
|
||||||
|
typedef typename Tr::Geom_traits::Vector_3 Vector;
|
||||||
|
typedef typename Tr::Edge Edge;
|
||||||
|
typedef typename Tr::Facet Facet;
|
||||||
|
typedef typename Tr::Finite_facets_iterator Finite_facets_iterator;
|
||||||
|
|
||||||
|
const Tr& tr = c2t3.triangulation();
|
||||||
|
VertexPointMap vpmap = get(boost::vertex_point, graph);
|
||||||
|
const typename Tr::size_type number_of_facets = c2t3.number_of_facets();
|
||||||
|
{
|
||||||
|
// Finite vertices coordinates.
|
||||||
|
Finite_facets_iterator fit = tr.finite_facets_begin();
|
||||||
|
std::set<Facet> oriented_set;
|
||||||
|
std::stack<Facet> stack;
|
||||||
|
|
||||||
|
CGAL_assertion_code(typename Tr::size_type nb_facets = 0; )
|
||||||
|
|
||||||
|
while (oriented_set.size() != number_of_facets) {
|
||||||
|
while ( fit->first->is_facet_on_surface(fit->second) == false ||
|
||||||
|
oriented_set.find(*fit) != oriented_set.end() ||
|
||||||
|
|
||||||
|
oriented_set.find(c2t3.opposite_facet(*fit)) !=
|
||||||
|
oriented_set.end() ) {
|
||||||
|
++fit;
|
||||||
|
}
|
||||||
|
oriented_set.insert(*fit);
|
||||||
|
stack.push(*fit);
|
||||||
|
while(! stack.empty() ) {
|
||||||
|
Facet f = stack.top();
|
||||||
|
stack.pop();
|
||||||
|
for(int ih = 0 ; ih < 3 ; ++ih) {
|
||||||
|
const int i1 = tr.vertex_triple_index(f.second, tr. cw(ih));
|
||||||
|
const int i2 = tr.vertex_triple_index(f.second, tr.ccw(ih));
|
||||||
|
if( c2t3.face_status(Edge(f.first, i1, i2)) == C2T3::REGULAR ) {
|
||||||
|
Facet fn = c2t3.neighbor(f, ih);
|
||||||
|
if (oriented_set.find(fn) == oriented_set.end() &&
|
||||||
|
oriented_set.find(c2t3.opposite_facet(fn)) == oriented_set.end())
|
||||||
|
{
|
||||||
|
oriented_set.insert(fn);
|
||||||
|
stack.push(fn);
|
||||||
|
}
|
||||||
|
} // end "if the edge is regular"
|
||||||
|
} // end "for each neighbor of f"
|
||||||
|
} // end "stack non empty"
|
||||||
|
} // end "oriented_set not full"
|
||||||
|
|
||||||
|
// Orients the whole mesh towards outside:
|
||||||
|
// - find the facet with max z
|
||||||
|
typename std::set<Facet>::const_iterator top_facet = oriented_set.begin();
|
||||||
|
for(typename std::set<Facet>::const_iterator fit = oriented_set.begin();
|
||||||
|
fit != oriented_set.end();
|
||||||
|
++fit)
|
||||||
|
{
|
||||||
|
double top_z =
|
||||||
|
(top_facet->first->vertex(tr.vertex_triple_index(top_facet->second, 0))->point().z()
|
||||||
|
+ top_facet->first->vertex(tr.vertex_triple_index(top_facet->second, 1))->point().z()
|
||||||
|
+ top_facet->first->vertex(tr.vertex_triple_index(top_facet->second, 2))->point().z())/3.;
|
||||||
|
double z =
|
||||||
|
(fit->first->vertex(tr.vertex_triple_index(fit->second, 0))->point().z()
|
||||||
|
+ fit->first->vertex(tr.vertex_triple_index(fit->second, 1))->point().z()
|
||||||
|
+ fit->first->vertex(tr.vertex_triple_index(fit->second, 2))->point().z())/3.;
|
||||||
|
if (top_z < z)
|
||||||
|
top_facet = fit;
|
||||||
|
}
|
||||||
|
// - orient the facet with max z towards +Z axis
|
||||||
|
Vertex_handle v0 = top_facet->first->vertex(tr.vertex_triple_index(top_facet->second, 0));
|
||||||
|
Vertex_handle v1 = top_facet->first->vertex(tr.vertex_triple_index(top_facet->second, 1));
|
||||||
|
Vertex_handle v2 = top_facet->first->vertex(tr.vertex_triple_index(top_facet->second, 2));
|
||||||
|
Vector normal = cross_product(v1->point()-v0->point(), v2->point()-v1->point());
|
||||||
|
const Vector Z(0, 0, 1);
|
||||||
|
bool regular_orientation = (Z * normal >= 0);
|
||||||
|
|
||||||
|
//used to set indices of vertices
|
||||||
|
std::map<Vertex_handle, int> V;
|
||||||
|
//int inum = 0;
|
||||||
|
|
||||||
|
//add vertices
|
||||||
|
std::vector<typename boost::graph_traits<FaceGraph>::vertex_descriptor> vertices;
|
||||||
|
for(Vertex_iterator vit = tr.vertices_begin();
|
||||||
|
vit != tr.vertices_end();
|
||||||
|
++vit)
|
||||||
|
{
|
||||||
|
|
||||||
|
typename boost::graph_traits<FaceGraph>::vertex_descriptor v = add_vertex(graph);
|
||||||
|
vertices.push_back(v);
|
||||||
|
put(vpmap,
|
||||||
|
v,
|
||||||
|
typename Tr::Point_3(
|
||||||
|
vit->point().x(),
|
||||||
|
vit->point().y(),
|
||||||
|
vit->point().z())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//add faces
|
||||||
|
for(typename std::set<Facet>::const_iterator fit =
|
||||||
|
oriented_set.begin();
|
||||||
|
fit != oriented_set.end();
|
||||||
|
++fit)
|
||||||
|
{
|
||||||
|
int id0(V[fit->first->vertex(tr.vertex_triple_index(fit->second, 0))]),
|
||||||
|
id1(regular_orientation ? V[fit->first->vertex(tr.vertex_triple_index(fit->second, 1))]
|
||||||
|
: V[fit->first->vertex(tr.vertex_triple_index(fit->second, 2))]),
|
||||||
|
id2(regular_orientation ? V[fit->first->vertex(tr.vertex_triple_index(fit->second, 2))]
|
||||||
|
: V[fit->first->vertex(tr.vertex_triple_index(fit->second, 1))]);
|
||||||
|
std::vector<typename boost::graph_traits<FaceGraph>::vertex_descriptor> face;
|
||||||
|
face.resize(3);
|
||||||
|
face[0] = vertices[id0];
|
||||||
|
face[1] = vertices[id1];
|
||||||
|
face[2] = vertices[id2];
|
||||||
|
CGAL::Euler::add_face(face, graph);
|
||||||
|
CGAL_assertion_code(++nb_facets);
|
||||||
|
}
|
||||||
|
CGAL_assertion(nb_facets == number_of_facets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CGAL_OUTPUT_SURFACE_FACETS_TO_FACEGRAPH_H
|
||||||
Loading…
Reference in New Issue