mirror of https://github.com/CGAL/cgal
Add a function generic_extrude_mesh() that takes up to 2 functors instead of a direction and a distance.
This commit is contained in:
parent
41d3c05f7f
commit
4efef4e15b
|
|
@ -22,7 +22,10 @@
|
||||||
|
|
||||||
#ifndef CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
#ifndef CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
||||||
#define CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
#define CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
||||||
|
|
||||||
#include <CGAL/license/Polygon_mesh_processing/meshing_hole_filling.h>
|
#include <CGAL/license/Polygon_mesh_processing/meshing_hole_filling.h>
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/Polygon_mesh_processing/orientation.h>
|
#include <CGAL/Polygon_mesh_processing/orientation.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
#include <CGAL/boost/graph/named_function_params.h>
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
|
|
@ -34,36 +37,46 @@ namespace CGAL {
|
||||||
namespace Polygon_mesh_processing {
|
namespace Polygon_mesh_processing {
|
||||||
namespace internal{
|
namespace internal{
|
||||||
|
|
||||||
template<typename PMAP>
|
template<typename PMAP, typename Vector>
|
||||||
struct ConstDistTranslation{
|
struct ConstDistTranslation{
|
||||||
ConstDistTranslation(PMAP map)
|
ConstDistTranslation(PMAP map, const Vector& dir, const double d)
|
||||||
:map(map){}
|
:map(map), dir(dir), d(d){}
|
||||||
|
|
||||||
template<typename VertexDescriptor, class Vector>
|
template<typename VertexDescriptor>
|
||||||
void operator()(const VertexDescriptor vd, const Vector& dir, const double d)
|
void operator()(const VertexDescriptor vd)
|
||||||
{
|
{
|
||||||
typename boost::property_traits<PMAP>::value_type p = get(map, vd) + d*dir;
|
typename boost::property_traits<PMAP>::value_type p = get(map, vd) + d*dir;
|
||||||
put(map, vd, p);
|
put(map, vd, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
PMAP map;
|
PMAP map;
|
||||||
|
Vector dir;
|
||||||
|
double d;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IdentityFunctor
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
void operator()(const T&){}
|
||||||
};
|
};
|
||||||
}//end internal
|
}//end internal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \ingroup PMP_meshing_grp
|
* \ingroup PMP_meshing_grp
|
||||||
* Extrudes `input` into `output` following the direction given by `dir` and
|
* Extrudes `input` into `output` using `bot` and `top`. It means that
|
||||||
* at a distance `d`.
|
* `input` will be copied twice and transformed once using `bot`, once using `top`,
|
||||||
|
* and these two copies will be joined with triangle strips.
|
||||||
* @tparam InputMesh a model of the concept `FaceListGraph`
|
* @tparam InputMesh a model of the concept `FaceListGraph`
|
||||||
* @tparam OutputMesh a model of the concept `FaceListGraph`
|
* @tparam OutputMesh a model of the concept `FaceListGraph`
|
||||||
* @tparam NamedParameters1 a sequence of \ref pmp_namedparameters "Named Parameters" for `InputMesh`
|
* @tparam NamedParameters1 a sequence of \ref pmp_namedparameters "Named Parameters" for `InputMesh`
|
||||||
* @tparam NamedParameters2 a sequence of \ref pmp_namedparameters "Named Parameters" for `OutputMesh`
|
* @tparam NamedParameters2 a sequence of \ref pmp_namedparameters "Named Parameters" for `OutputMesh`
|
||||||
* @tparam BottomFunctor a functor that will apply a transformation to all points of
|
* @tparam BottomFunctor a functor that will apply a transformation to all points of
|
||||||
* `input` in order to create the offsetted part of the extrusion. It must have a function
|
* `input` in order to create the first offsetted part of the extrusion. It must have a function
|
||||||
* `void operator()(boost::graph_traits<OutputMesh>::vertex_descriptor, Vector_3 dir, const FT d)`
|
* `void operator()(boost::graph_traits<OutputMesh>::vertex_descriptor);
|
||||||
* The default is the
|
* @tparam TopFunctor a functor that will apply a transformation to all points of
|
||||||
* translation along `dir` of the constant distance `d`.
|
* `input` in order to create the second offsetted part of the extrusion. It must have a function
|
||||||
* @param input the closed triangulated `InputMesh` to extrude.
|
* `void operator()(boost::graph_traits<OutputMesh>::vertex_descriptor);
|
||||||
|
* @param input the open triangulated `InputMesh` to extrude.
|
||||||
* @param output the `OutputMesh` containing the result of the extrusion.
|
* @param output the `OutputMesh` containing the result of the extrusion.
|
||||||
* @param np1 an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
* @param np1 an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||||
*
|
*
|
||||||
|
|
@ -85,27 +98,19 @@ struct ConstDistTranslation{
|
||||||
*/
|
*/
|
||||||
template <class InputMesh,
|
template <class InputMesh,
|
||||||
class OutputMesh,
|
class OutputMesh,
|
||||||
|
class BottomFunctor,
|
||||||
|
class TopFunctor = internal::IdentityFunctor,
|
||||||
class NamedParameters1,
|
class NamedParameters1,
|
||||||
class NamedParameters2,
|
class NamedParameters2
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
class BottomFunctor
|
|
||||||
#else
|
|
||||||
class BottomFunctor=internal::ConstDistTranslation<
|
|
||||||
typename GetVertexPointMap<OutputMesh, NamedParameters2>::type>
|
|
||||||
#endif
|
|
||||||
>
|
>
|
||||||
void extrude_mesh(const InputMesh& input,
|
void generic_extrude_mesh(const InputMesh& input,
|
||||||
OutputMesh& output,
|
OutputMesh& output,
|
||||||
#ifdef DOXYGEN_RUNNING
|
BottomFunctor& bot,
|
||||||
Vector_3 dir,
|
TopFunctor& top,
|
||||||
const FT d,
|
const NamedParameters1& np1,
|
||||||
#else
|
const NamedParameters2& np2)
|
||||||
typename GetGeomTraits<OutputMesh, NamedParameters2>::type::Vector_3 dir,
|
|
||||||
const typename GetGeomTraits<OutputMesh, NamedParameters2>::type::FT d,
|
|
||||||
#endif
|
|
||||||
const NamedParameters1& np1,
|
|
||||||
const NamedParameters2& np2)
|
|
||||||
{
|
{
|
||||||
|
typedef typename boost::graph_traits<InputMesh>::vertex_descriptor input_vertex_descriptor;
|
||||||
typedef typename boost::graph_traits<InputMesh>::halfedge_descriptor input_halfedge_descriptor;
|
typedef typename boost::graph_traits<InputMesh>::halfedge_descriptor input_halfedge_descriptor;
|
||||||
|
|
||||||
typedef typename boost::graph_traits<OutputMesh>::vertex_descriptor output_vertex_descriptor;
|
typedef typename boost::graph_traits<OutputMesh>::vertex_descriptor output_vertex_descriptor;
|
||||||
|
|
@ -122,32 +127,36 @@ void extrude_mesh(const InputMesh& input,
|
||||||
IVPMap input_vpm = choose_param(get_param(np1, internal_np::vertex_point),
|
IVPMap input_vpm = choose_param(get_param(np1, internal_np::vertex_point),
|
||||||
get_const_property_map(vertex_point, input));
|
get_const_property_map(vertex_point, input));
|
||||||
|
|
||||||
boost::unordered_map<input_halfedge_descriptor, output_halfedge_descriptor> offset_h2h;
|
boost::unordered_map<input_halfedge_descriptor, output_halfedge_descriptor> bottom_h2h;
|
||||||
copy_face_graph(input, output, Emptyset_iterator(),
|
copy_face_graph(input, output, Emptyset_iterator(),
|
||||||
std::inserter(offset_h2h, offset_h2h.end()), Emptyset_iterator(),
|
std::inserter(bottom_h2h, bottom_h2h.end()), Emptyset_iterator(),
|
||||||
input_vpm, output_vpm);
|
input_vpm, output_vpm);
|
||||||
|
|
||||||
BottomFunctor bottom_functor(output_vpm);
|
|
||||||
// create the offset for the other side
|
// create the offset for the other side
|
||||||
BOOST_FOREACH(output_vertex_descriptor v, vertices(output))
|
BOOST_FOREACH(output_vertex_descriptor v, vertices(output))
|
||||||
{
|
{
|
||||||
bottom_functor(v, dir, d);
|
bot(v);
|
||||||
}
|
}
|
||||||
CGAL::Polygon_mesh_processing::reverse_face_orientations(output);
|
CGAL::Polygon_mesh_processing::reverse_face_orientations(output);
|
||||||
|
|
||||||
// collect border halfedges for the creation of the triangle strip
|
// collect border halfedges for the creation of the triangle strip
|
||||||
boost::unordered_map<input_halfedge_descriptor, output_halfedge_descriptor> h2h;
|
boost::unordered_map<input_vertex_descriptor, output_vertex_descriptor> top_v2v;
|
||||||
copy_face_graph(input, output, CGAL::Emptyset_iterator(),
|
boost::unordered_map<input_halfedge_descriptor, output_halfedge_descriptor> top_h2h;
|
||||||
std::inserter(h2h, h2h.end()), Emptyset_iterator(),
|
copy_face_graph(input, output, std::inserter(top_v2v, top_v2v.end()),
|
||||||
|
std::inserter(top_h2h, top_h2h.end()), Emptyset_iterator(),
|
||||||
input_vpm, output_vpm);
|
input_vpm, output_vpm);
|
||||||
|
BOOST_FOREACH(input_vertex_descriptor v, vertices(input))
|
||||||
|
{
|
||||||
|
top(top_v2v[v]);
|
||||||
|
}
|
||||||
std::vector<output_halfedge_descriptor> border_hedges;
|
std::vector<output_halfedge_descriptor> border_hedges;
|
||||||
std::vector<output_halfedge_descriptor> offset_border_hedges;
|
std::vector<output_halfedge_descriptor> offset_border_hedges;
|
||||||
BOOST_FOREACH(input_halfedge_descriptor h, halfedges(input))
|
BOOST_FOREACH(input_halfedge_descriptor h, halfedges(input))
|
||||||
{
|
{
|
||||||
if( CGAL::is_border(h, input) )
|
if( CGAL::is_border(h, input) )
|
||||||
{
|
{
|
||||||
border_hedges.push_back(h2h[h]);
|
border_hedges.push_back(top_h2h[h]);
|
||||||
offset_border_hedges.push_back(offset_h2h[h]);
|
offset_border_hedges.push_back(bottom_h2h[h]);
|
||||||
CGAL_assertion(is_border(border_hedges.back(), output));
|
CGAL_assertion(is_border(border_hedges.back(), output));
|
||||||
CGAL_assertion(is_border(offset_border_hedges.back(), output));
|
CGAL_assertion(is_border(offset_border_hedges.back(), output));
|
||||||
}
|
}
|
||||||
|
|
@ -222,6 +231,62 @@ void extrude_mesh(const InputMesh& input,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup PMP_meshing_grp
|
||||||
|
* Extrudes `input` into `output` following the direction given by `dir` and
|
||||||
|
* at a distance `d`.
|
||||||
|
* @tparam InputMesh a model of the concept `FaceListGraph`
|
||||||
|
* @tparam OutputMesh a model of the concept `FaceListGraph`
|
||||||
|
* @tparam NamedParameters1 a sequence of \ref pmp_namedparameters "Named Parameters" for `InputMesh`
|
||||||
|
* @tparam NamedParameters2 a sequence of \ref pmp_namedparameters "Named Parameters" for `OutputMesh`
|
||||||
|
* @param input the open triangulated `InputMesh` to extrude.
|
||||||
|
* @param output the `OutputMesh` containing the result of the extrusion.
|
||||||
|
* @param np1 an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
*
|
||||||
|
* \cgalNamedParamsBegin
|
||||||
|
* \cgalParamBegin{vertex_point_map}
|
||||||
|
* the property map that will contain the points associated to the vertices of `output`.
|
||||||
|
* If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||||
|
* should be available for the vertices of `output` \cgalParamEnd
|
||||||
|
* \cgalNamedParamsEnd
|
||||||
|
*
|
||||||
|
* * @param np2 an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
*
|
||||||
|
* \cgalNamedParamsBegin
|
||||||
|
* \cgalParamBegin{vertex_point_map}
|
||||||
|
* the property map that contains the points associated to the vertices of `input`.
|
||||||
|
* If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||||
|
* should be available for the vertices of `input` \cgalParamEnd
|
||||||
|
* \cgalNamedParamsEnd
|
||||||
|
*/
|
||||||
|
template <class InputMesh,
|
||||||
|
class OutputMesh,
|
||||||
|
class NamedParameters1,
|
||||||
|
class NamedParameters2>
|
||||||
|
void extrude_mesh(const InputMesh& input,
|
||||||
|
OutputMesh& output,
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
|
Vector_3 dir,
|
||||||
|
const FT d,
|
||||||
|
#else
|
||||||
|
typename GetGeomTraits<OutputMesh, NamedParameters2>::type::Vector_3 dir,
|
||||||
|
const typename GetGeomTraits<OutputMesh, NamedParameters2>::type::FT d,
|
||||||
|
#endif
|
||||||
|
const NamedParameters1& np1,
|
||||||
|
const NamedParameters2& np2)
|
||||||
|
{
|
||||||
|
typedef typename GetVertexPointMap < OutputMesh, NamedParameters2>::type VPMap;
|
||||||
|
VPMap output_vpm = choose_param(get_param(np2, internal_np::vertex_point),
|
||||||
|
get_property_map(vertex_point, output));
|
||||||
|
|
||||||
|
internal::ConstDistTranslation<
|
||||||
|
typename GetVertexPointMap<OutputMesh, NamedParameters2>::type,
|
||||||
|
typename GetGeomTraits<OutputMesh, NamedParameters2>::type::Vector_3> bot(output_vpm,
|
||||||
|
dir, d);
|
||||||
|
internal::IdentityFunctor top;
|
||||||
|
generic_extrude_mesh(input, output, bot,top, np1, np2);
|
||||||
|
}
|
||||||
//convenience overload
|
//convenience overload
|
||||||
template <class InputMesh,
|
template <class InputMesh,
|
||||||
class OutputMesh,
|
class OutputMesh,
|
||||||
|
|
@ -236,5 +301,30 @@ void extrude_mesh(const InputMesh& input,
|
||||||
parameters::all_default());
|
parameters::all_default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class InputMesh,
|
||||||
|
class OutputMesh,
|
||||||
|
class BottomFunctor,
|
||||||
|
class TopFunctor>
|
||||||
|
void generic_extrude_mesh(const InputMesh& input,
|
||||||
|
OutputMesh& output,
|
||||||
|
BottomFunctor& bot,
|
||||||
|
TopFunctor& top)
|
||||||
|
{
|
||||||
|
generic_extrude_mesh(input, output, bot, top,
|
||||||
|
parameters::all_default(), parameters::all_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class InputMesh,
|
||||||
|
class OutputMesh,
|
||||||
|
class BottomFunctor>
|
||||||
|
void generic_extrude_mesh(const InputMesh& input,
|
||||||
|
OutputMesh& output,
|
||||||
|
BottomFunctor& bot)
|
||||||
|
{
|
||||||
|
internal::IdentityFunctor top;
|
||||||
|
generic_extrude_mesh(input, output, bot, top,
|
||||||
|
parameters::all_default(), parameters::all_default());
|
||||||
|
}
|
||||||
|
|
||||||
}} //end CGAL::PMP
|
}} //end CGAL::PMP
|
||||||
#endif //CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
#endif //CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,32 @@
|
||||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
typedef CGAL::Surface_mesh<Kernel::Point_3> SMesh;
|
typedef CGAL::Surface_mesh<Kernel::Point_3> SMesh;
|
||||||
|
|
||||||
|
template<typename MAP>
|
||||||
|
struct Bot
|
||||||
|
{
|
||||||
|
Bot(MAP map):map(map){}
|
||||||
|
template<typename VD>
|
||||||
|
void operator()(VD vd)
|
||||||
|
{
|
||||||
|
put(map, vd, get(map, vd)+Kernel::Vector_3(-2.0,0.0,-1.0));
|
||||||
|
}
|
||||||
|
MAP map;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename MAP>
|
||||||
|
struct Top
|
||||||
|
{
|
||||||
|
Top(MAP map):map(map){}
|
||||||
|
|
||||||
|
template<typename VD>
|
||||||
|
void operator()(VD vd)
|
||||||
|
{
|
||||||
|
put(map, vd, get(map, vd)+Kernel::Vector_3(0.0,2.0,1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
MAP map;
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
|
@ -25,7 +50,16 @@ int main(int argc, char* argv[])
|
||||||
CGAL::Polygon_mesh_processing::extrude_mesh(in, out, Kernel::Vector_3(0.0, 0.0, -1.0), 1.0);
|
CGAL::Polygon_mesh_processing::extrude_mesh(in, out, Kernel::Vector_3(0.0, 0.0, -1.0), 1.0);
|
||||||
std::ofstream extruded_off("extruded.off");
|
std::ofstream extruded_off("extruded.off");
|
||||||
extruded_off << out;
|
extruded_off << out;
|
||||||
extruded_off.close();
|
extruded_off.close();
|
||||||
|
out.clear();
|
||||||
|
|
||||||
|
typedef typename boost::property_map<SMesh, CGAL::vertex_point_t>::type VPMap;
|
||||||
|
Bot<VPMap> bot(get(CGAL::vertex_point, out));
|
||||||
|
Top<VPMap> top(get(CGAL::vertex_point, out));
|
||||||
|
CGAL::Polygon_mesh_processing::generic_extrude_mesh(in, out, bot, top);
|
||||||
|
std::ofstream gen_extruded_off("gen_extruded.off");
|
||||||
|
gen_extruded_off << out;
|
||||||
|
gen_extruded_off.close();
|
||||||
std::cerr << "All done." << std::endl;
|
std::cerr << "All done." << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue