mirror of https://github.com/CGAL/cgal
add a function to stitch boundary edges in a polyhedron
also brings: a demo plugin that also display boundary edges a testsuite with examples
This commit is contained in:
parent
a3a3e9f69d
commit
05bff9cf8f
|
|
@ -0,0 +1,269 @@
|
|||
// Copyright (c) 2014 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) : Sebastien Loriot
|
||||
|
||||
|
||||
#ifndef CGAL_POLYHEDRON_STITCHING_H
|
||||
#define CGAL_POLYHEDRON_STITCHING_H
|
||||
|
||||
#include <CGAL/Modifier_base.h>
|
||||
#include <CGAL/HalfedgeDS_decorator.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace CGAL{
|
||||
|
||||
namespace Polyhedron_stitching{
|
||||
|
||||
template <class Halfedge_handle, class Point_3>
|
||||
struct Less_for_halfedge{
|
||||
bool operator()( Halfedge_handle h1, Halfedge_handle h2 ) const
|
||||
{
|
||||
const Point_3& s1=h1->opposite()->vertex()->point();
|
||||
const Point_3& t1=h1->vertex()->point();
|
||||
const Point_3& s2=h2->opposite()->vertex()->point();
|
||||
const Point_3& t2=h2->vertex()->point();
|
||||
return
|
||||
( s1 < t1? std::make_pair(s1,t1) : std::make_pair(t1, s1) )
|
||||
<
|
||||
( s2 < t2? std::make_pair(s2,t2) : std::make_pair(t2, s2) );
|
||||
}
|
||||
};
|
||||
|
||||
template <class LessHedge, class Polyhedron, class OutputIterator>
|
||||
OutputIterator
|
||||
detect_duplicated_boundary_edges
|
||||
(Polyhedron& P, OutputIterator out, LessHedge less_hedge)
|
||||
{
|
||||
typedef typename Polyhedron::Halfedge_handle Halfedge_handle;
|
||||
|
||||
P.normalize_border();
|
||||
|
||||
typedef
|
||||
std::set<Halfedge_handle, LessHedge > Border_halfedge_set;
|
||||
Border_halfedge_set border_halfedge_set(less_hedge);
|
||||
for (typename Polyhedron::Halfedge_iterator
|
||||
it=P.border_halfedges_begin(), it_end=P.halfedges_end();
|
||||
it!=it_end; ++it)
|
||||
{
|
||||
if ( !it->is_border() ) continue;
|
||||
typename Border_halfedge_set::iterator set_it;
|
||||
bool insertion_ok;
|
||||
CGAL::cpp11::tie(set_it,insertion_ok)=
|
||||
border_halfedge_set.insert(it);
|
||||
|
||||
if ( !insertion_ok ) *out++=std::make_pair(*set_it, it);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class Polyhedron>
|
||||
struct Naive_border_stitching_modifier:
|
||||
CGAL::Modifier_base<typename Polyhedron::HalfedgeDS>
|
||||
{
|
||||
typedef typename Polyhedron::HalfedgeDS HDS;
|
||||
typedef typename HDS::Halfedge_handle Halfedge_handle;
|
||||
typedef typename HDS::Vertex_handle Vertex_handle;
|
||||
typedef typename HDS::Halfedge::Base HBase;
|
||||
|
||||
std::vector <std::pair<Halfedge_handle,Halfedge_handle> >& hedge_pairs_to_stitch;
|
||||
|
||||
Naive_border_stitching_modifier(
|
||||
std::vector< std::pair<Halfedge_handle,Halfedge_handle> >&
|
||||
hedge_pairs_to_stitch_) :hedge_pairs_to_stitch(hedge_pairs_to_stitch_)
|
||||
{}
|
||||
|
||||
void update_target_vertex(Halfedge_handle h,
|
||||
Vertex_handle v,
|
||||
CGAL::HalfedgeDS_decorator<HDS>& decorator)
|
||||
{
|
||||
Halfedge_handle start=h;
|
||||
do{
|
||||
decorator.set_vertex(h, v);
|
||||
h=h->next()->opposite();
|
||||
} while( h!=start );
|
||||
decorator.set_vertex_halfedge(v, h);
|
||||
}
|
||||
|
||||
|
||||
void operator() (HDS& hds)
|
||||
{
|
||||
std::size_t nb_hedges=hedge_pairs_to_stitch.size();
|
||||
|
||||
std::set <Halfedge_handle> hedges_to_stitch;
|
||||
for (std::size_t k=0; k<nb_hedges; ++k)
|
||||
{
|
||||
hedges_to_stitch.insert( hedge_pairs_to_stitch[k].first );
|
||||
hedges_to_stitch.insert( hedge_pairs_to_stitch[k].second );
|
||||
}
|
||||
|
||||
CGAL::HalfedgeDS_decorator<HDS> decorator(hds);
|
||||
for (std::size_t k=0; k<nb_hedges; ++k)
|
||||
{
|
||||
Halfedge_handle h1=hedge_pairs_to_stitch[k].first;
|
||||
Halfedge_handle h2=hedge_pairs_to_stitch[k].second;
|
||||
|
||||
CGAL_assertion(h1->vertex()->point() == h2->opposite()->vertex()->point() );
|
||||
CGAL_assertion(h2->vertex()->point() == h1->opposite()->vertex()->point() );
|
||||
CGAL_assertion( h1->is_border() );
|
||||
CGAL_assertion( h2->is_border() );
|
||||
CGAL_assertion( !h1->opposite()->is_border() );
|
||||
CGAL_assertion( !h2->opposite()->is_border() );
|
||||
|
||||
//update next/prev of neighbor halfedges
|
||||
if ( hedges_to_stitch.find(h1->next())==hedges_to_stitch.end() )
|
||||
{
|
||||
CGAL_assertion( hedges_to_stitch.find(h2->prev())==hedges_to_stitch.end() );
|
||||
Halfedge_handle prev=h2->prev();
|
||||
Halfedge_handle next=h1->next();
|
||||
prev->HBase::set_next(next);
|
||||
decorator.set_prev(next, prev);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGAL_assertion( hedges_to_stitch.find(h2->prev())!=hedges_to_stitch.end() );
|
||||
}
|
||||
|
||||
if ( hedges_to_stitch.find(h2->next())==hedges_to_stitch.end() )
|
||||
{
|
||||
CGAL_assertion( hedges_to_stitch.find(h1->prev())==hedges_to_stitch.end() );
|
||||
Halfedge_handle prev=h1->prev();
|
||||
Halfedge_handle next=h2->next();
|
||||
prev->HBase::set_next(next);
|
||||
decorator.set_prev(next, prev);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGAL_assertion( hedges_to_stitch.find(h1->prev())!=hedges_to_stitch.end() );
|
||||
}
|
||||
|
||||
//we are going to remove h2 and its opposite
|
||||
//set face-halfedge relationship
|
||||
decorator.set_face(h1,h2->opposite()->face());
|
||||
decorator.set_face_halfedge(h1->face(),h1);
|
||||
//update next/prev pointers
|
||||
Halfedge_handle tmp=h2->opposite()->prev();
|
||||
tmp->HBase::set_next(h1);
|
||||
decorator.set_prev(h1,tmp);
|
||||
tmp=h2->opposite()->next();
|
||||
h1->HBase::set_next(tmp);
|
||||
decorator.set_prev(tmp,h1);
|
||||
|
||||
//remove h2
|
||||
hds.edges_erase(h2);
|
||||
}
|
||||
|
||||
//now update the vertex-halfedge relationship
|
||||
std::vector<Vertex_handle> vertices_to_delete;
|
||||
for (std::size_t k=0; k<nb_hedges; ++k)
|
||||
{
|
||||
Halfedge_handle h1=hedge_pairs_to_stitch[k].first;
|
||||
Vertex_handle h1_tgt=h1->vertex();
|
||||
Vertex_handle h2_src=h1->next()->opposite()->vertex();
|
||||
|
||||
//update vertex pointers: target of h1 vs source of h2
|
||||
if ( h1_tgt != h2_src )
|
||||
{
|
||||
CGAL_assertion( h1_tgt->point() == h2_src->point() );
|
||||
//we remove h2->opposite()->vertex()
|
||||
vertices_to_delete.push_back( h2_src );
|
||||
update_target_vertex(h1, h1_tgt,decorator);
|
||||
}
|
||||
else
|
||||
decorator.set_vertex_halfedge(h1_tgt, h1);
|
||||
|
||||
Vertex_handle h1_src=h1->opposite()->vertex();
|
||||
Vertex_handle h2_tgt=h1->prev()->vertex();
|
||||
//update vertex pointers: target of h1 vs source of h2
|
||||
if ( h1_src!= h2_tgt )
|
||||
{
|
||||
CGAL_assertion( h1_src->point() == h2_tgt->point() );
|
||||
//we remove h1->opposite()->vertex()
|
||||
vertices_to_delete.push_back( h1_src );
|
||||
update_target_vertex(h1->opposite(), h2_tgt,decorator);
|
||||
}
|
||||
else
|
||||
decorator.set_vertex_halfedge(h1_src, h1->opposite());
|
||||
}
|
||||
|
||||
for(typename std::vector<Vertex_handle>::iterator
|
||||
itv=vertices_to_delete.begin(),itv_end=vertices_to_delete.end();
|
||||
itv!=itv_end; ++itv)
|
||||
{
|
||||
hds.vertices_erase(*itv);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} //end of namespace Polyhedron_stitching
|
||||
|
||||
/// Stitches together border halfedges in a polyhedron.
|
||||
/// The halfedge to be stitched are provided in `hedge_pairs_to_stitch`.
|
||||
/// Foreach pair `p` in this vector, p.second and its opposite will be removed
|
||||
/// from `P`.
|
||||
/// The vertices that get removed from `P` are selected as follow:
|
||||
/// The pair of halfedges in `hedge_pairs_to_stitch` are processed linearly.
|
||||
/// Let `p` be such a pair.
|
||||
/// If the target of p.first has not been marked for deletion,
|
||||
/// then the source of p.second is.
|
||||
/// If the target of p.second has not been marked for deletion,
|
||||
/// then the source of p.first is.
|
||||
template <class Polyhedron>
|
||||
void polyhedron_stitching(
|
||||
Polyhedron& P,
|
||||
std::vector <std::pair<typename Polyhedron::Halfedge_handle,
|
||||
typename Polyhedron::Halfedge_handle> >&
|
||||
hedge_pairs_to_stitch)
|
||||
{
|
||||
Polyhedron_stitching::Naive_border_stitching_modifier<Polyhedron>
|
||||
modifier(hedge_pairs_to_stitch);
|
||||
P.delegate(modifier);
|
||||
}
|
||||
|
||||
/// Same as above but the pair of halfedges to be stitched are found
|
||||
/// using `less_hedge`. Two halfedges `h1` and `h2` are set to be stitched
|
||||
/// if `less_hedge(h1,h2)=less_hedge(h2,h1)=true`.
|
||||
/// `LessHedge` is a key comparison function that is used to sort halfedges
|
||||
template <class Polyhedron, class LessHedge>
|
||||
void polyhedron_stitching(Polyhedron& P, LessHedge less_hedge)
|
||||
{
|
||||
typedef typename Polyhedron::Halfedge_handle Halfedge_handle;
|
||||
|
||||
std::vector <std::pair<Halfedge_handle,Halfedge_handle> > hedge_pairs_to_stitch;
|
||||
Polyhedron_stitching::detect_duplicated_boundary_edges(
|
||||
P, std::back_inserter(hedge_pairs_to_stitch), less_hedge );
|
||||
polyhedron_stitching(P, hedge_pairs_to_stitch);
|
||||
}
|
||||
|
||||
/// Same as above using the sorted pair of vertices incidents to the halfedges
|
||||
/// as comparision
|
||||
template <class Polyhedron>
|
||||
void polyhedron_stitching(Polyhedron& P)
|
||||
{
|
||||
typedef typename Polyhedron::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Polyhedron::Vertex::Point_3 Point_3;
|
||||
|
||||
Polyhedron_stitching::Less_for_halfedge<Halfedge_handle, Point_3> less_hedge;
|
||||
polyhedron_stitching(P, less_hedge);
|
||||
}
|
||||
|
||||
} //end of namespace CGAL
|
||||
|
||||
|
||||
#endif //CGAL_POLYHEDRON_STITCHING_H
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
OFF
|
||||
20 16 0
|
||||
|
||||
1 0 0
|
||||
0.75 0 0
|
||||
0.5 0 0
|
||||
0.25 0 0
|
||||
0 0 0
|
||||
0 1 0
|
||||
0.25 1 0
|
||||
0.5 1 0
|
||||
0.75 1 0
|
||||
1 1 0
|
||||
1 1 0
|
||||
0.75 1 0
|
||||
0.5 1 0
|
||||
0.25 1 0
|
||||
0 1 0
|
||||
0 2 0
|
||||
0.25 2 0
|
||||
0.5 2 0
|
||||
0.75 2 0
|
||||
1 2 0
|
||||
3 3 6 2
|
||||
3 2 6 7
|
||||
3 5 6 3
|
||||
3 1 2 7
|
||||
3 5 3 4
|
||||
3 1 7 8
|
||||
3 1 8 0
|
||||
3 8 9 0
|
||||
3 13 16 12
|
||||
3 12 16 17
|
||||
3 15 16 13
|
||||
3 11 12 17
|
||||
3 15 13 14
|
||||
3 11 17 18
|
||||
3 11 18 10
|
||||
3 18 19 10
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
OFF
|
||||
20 8 0
|
||||
1 0 0
|
||||
0.75 0 0
|
||||
0.5 0 0
|
||||
0.25 0 0
|
||||
0 0 0
|
||||
0 1 0
|
||||
0.25 1 0
|
||||
0.5 1 0
|
||||
0.75 1 0
|
||||
1 1 0
|
||||
1 1 0
|
||||
0.75 1 0
|
||||
0.5 1 0
|
||||
0.25 1 0
|
||||
0 1 0
|
||||
0 2 0
|
||||
0.25 2 0
|
||||
0.5 2 0
|
||||
0.75 2 0
|
||||
1 2 0
|
||||
4 5 6 3 4
|
||||
4 3 6 7 2
|
||||
4 1 2 7 8
|
||||
4 1 8 9 0
|
||||
4 15 16 13 14
|
||||
4 13 16 17 12
|
||||
4 11 12 17 18
|
||||
4 11 18 19 10
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
OFF
|
||||
17 16 0
|
||||
|
||||
1 0 0
|
||||
0.75 0 0
|
||||
0.5 0 0
|
||||
0.25 0 0
|
||||
0 0 0
|
||||
0 1 0
|
||||
0.25 1 0
|
||||
0.5 1 0
|
||||
0.75 1 0
|
||||
1 1 0
|
||||
1 1 0
|
||||
0.75 1 0
|
||||
0 2 0
|
||||
0.25 2 0
|
||||
0.5 2 0
|
||||
0.75 2 0
|
||||
1 2 0
|
||||
3 3 6 2
|
||||
3 2 6 7
|
||||
3 5 6 3
|
||||
3 1 2 7
|
||||
3 5 3 4
|
||||
3 1 7 8
|
||||
3 1 8 0
|
||||
3 8 9 0
|
||||
3 6 13 7
|
||||
3 7 13 14
|
||||
3 12 13 6
|
||||
3 11 7 14
|
||||
3 12 6 5
|
||||
3 11 14 15
|
||||
3 11 15 10
|
||||
3 15 16 10
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
OFF
|
||||
16 16 0
|
||||
|
||||
1 0 0
|
||||
0.75 0 0
|
||||
0.5 0 0
|
||||
0.25 0 0
|
||||
0 0 0
|
||||
0 1 0
|
||||
0.25 1 0
|
||||
0.5 1 0
|
||||
0.75 1 0
|
||||
1 1 0
|
||||
0.5 1 0
|
||||
0 2 0
|
||||
0.25 2 0
|
||||
0.5 2 0
|
||||
0.75 2 0
|
||||
1 2 0
|
||||
3 3 6 2
|
||||
3 2 6 7
|
||||
3 5 6 3
|
||||
3 1 2 7
|
||||
3 5 3 4
|
||||
3 1 7 8
|
||||
3 1 8 0
|
||||
3 8 9 0
|
||||
3 6 12 10
|
||||
3 10 12 13
|
||||
3 11 12 6
|
||||
3 8 10 13
|
||||
3 11 6 5
|
||||
3 8 13 14
|
||||
3 8 14 9
|
||||
3 14 15 9
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
OFF
|
||||
40 32 0
|
||||
|
||||
1 0 0
|
||||
0.75 0 0
|
||||
0.5 0 0
|
||||
0.25 0 0
|
||||
0 0 0
|
||||
0 1 0
|
||||
0.25 1 0
|
||||
0.5 1 0
|
||||
0.75 1 0
|
||||
1 1 0
|
||||
1 1 0
|
||||
0.75 1 0
|
||||
0.5 1 0
|
||||
0.25 1 0
|
||||
0 1 0
|
||||
0 2 0
|
||||
0.25 2 0
|
||||
0.5 2 0
|
||||
0.75 2 0
|
||||
1 2 0
|
||||
2 0 0
|
||||
1.75 0 0
|
||||
1.5 0 0
|
||||
1.25 0 0
|
||||
1 0 0
|
||||
1 1 0
|
||||
1.25 1 0
|
||||
1.5 1 0
|
||||
1.75 1 0
|
||||
2 1 0
|
||||
2 1 0
|
||||
1.75 1 0
|
||||
1.5 1 0
|
||||
1.25 1 0
|
||||
1 1 0
|
||||
1 2 0
|
||||
1.25 2 0
|
||||
1.5 2 0
|
||||
1.75 2 0
|
||||
2 2 0
|
||||
|
||||
3 3 6 2
|
||||
3 2 6 7
|
||||
3 5 6 3
|
||||
3 1 2 7
|
||||
3 5 3 4
|
||||
3 1 7 8
|
||||
3 1 8 0
|
||||
3 8 9 0
|
||||
3 13 16 12
|
||||
3 12 16 17
|
||||
3 15 16 13
|
||||
3 11 12 17
|
||||
3 15 13 14
|
||||
3 11 17 18
|
||||
3 11 18 10
|
||||
3 18 19 10
|
||||
3 23 26 22
|
||||
3 22 26 27
|
||||
3 25 26 23
|
||||
3 21 22 27
|
||||
3 25 23 24
|
||||
3 21 27 28
|
||||
3 21 28 20
|
||||
3 28 29 20
|
||||
3 33 36 32
|
||||
3 32 36 37
|
||||
3 35 36 33
|
||||
3 31 32 37
|
||||
3 35 33 34
|
||||
3 31 37 38
|
||||
3 31 38 30
|
||||
3 38 39 30
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/Polyhedron_stitching.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Polyhedron_3<K> Polyhedron;
|
||||
|
||||
void test(const char* fname)
|
||||
{
|
||||
std::cout << "Testing " << fname << "..." << std::flush;
|
||||
std::ifstream input(fname);
|
||||
Polyhedron P;
|
||||
input >> P;
|
||||
|
||||
CGAL::polyhedron_stitching(P);
|
||||
|
||||
std::ofstream output("output.off");
|
||||
output << P;
|
||||
output.close();
|
||||
|
||||
assert(P.is_valid(false, 5));
|
||||
std::cout << "OK\n";
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test("F17.off");
|
||||
test("full_border.off");
|
||||
test("full_border_quads.off");
|
||||
test("half_border.off");
|
||||
test("mid_border.off");
|
||||
test("multiple_incidence.off");
|
||||
}
|
||||
|
||||
|
|
@ -376,6 +376,9 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
|||
polyhedron_demo_plugin(self_intersection_plugin Polyhedron_demo_self_intersection_plugin)
|
||||
target_link_libraries(self_intersection_plugin scene_polyhedron_item)
|
||||
|
||||
polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_demo_polyhedron_stitching_plugin)
|
||||
target_link_libraries(polyhedron_stitching_plugin scene_polyhedron_item scene_polylines_item)
|
||||
|
||||
polyhedron_demo_plugin(subdivision_methods_plugin Polyhedron_demo_subdivision_methods_plugin)
|
||||
target_link_libraries(subdivision_methods_plugin scene_polyhedron_item)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QMainWindow>
|
||||
#include "Kernel_type.h"
|
||||
#include "Polyhedron_type.h"
|
||||
#include "Scene_polyhedron_item.h"
|
||||
#include "Scene_polylines_item.h"
|
||||
|
||||
#include "Polyhedron_demo_plugin_helper.h"
|
||||
#include "Polyhedron_demo_plugin_interface.h"
|
||||
|
||||
#include <CGAL/Polyhedron_stitching.h>
|
||||
|
||||
|
||||
class Polyhedron_demo_polyhedron_stitching_plugin :
|
||||
public QObject,
|
||||
public Polyhedron_demo_plugin_helper
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(Polyhedron_demo_plugin_interface)
|
||||
QAction* actionDetectBorders;
|
||||
QAction* actionStitchBorders;
|
||||
public:
|
||||
QList<QAction*> actions() const { return QList<QAction*>() << actionDetectBorders << actionStitchBorders; }
|
||||
void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* /* m */)
|
||||
{
|
||||
actionDetectBorders= new QAction(tr("Detect polyhedron boundaries"), mainWindow);
|
||||
actionStitchBorders= new QAction(tr("Stitch polyhedron duplicated boundaries"), mainWindow);
|
||||
actionDetectBorders->setObjectName("actionDetectBorders");
|
||||
actionStitchBorders->setObjectName("actionStitchBorders");
|
||||
Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface);
|
||||
}
|
||||
|
||||
bool applicable() const {
|
||||
return qobject_cast<Scene_polyhedron_item*>(scene->item(scene->mainSelectionIndex()));
|
||||
}
|
||||
|
||||
public slots:
|
||||
void on_actionDetectBorders_triggered();
|
||||
void on_actionStitchBorders_triggered();
|
||||
|
||||
}; // end Polyhedron_demo_polyhedron_stitching_plugin
|
||||
|
||||
void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_triggered()
|
||||
{
|
||||
Scene_interface::Item_id index = scene->mainSelectionIndex();
|
||||
|
||||
Scene_polyhedron_item* item =
|
||||
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
|
||||
|
||||
if(item)
|
||||
{
|
||||
Scene_polylines_item* new_item = new Scene_polylines_item();
|
||||
|
||||
Polyhedron* pMesh = item->polyhedron();
|
||||
pMesh->normalize_border();
|
||||
|
||||
for (Polyhedron::Halfedge_iterator
|
||||
it=pMesh->border_halfedges_begin(), it_end=pMesh->halfedges_end();
|
||||
it!=it_end; ++it)
|
||||
{
|
||||
if (!it->is_border()) continue;
|
||||
/// \todo build cycles and graph with nodes of valence 2.
|
||||
new_item->polylines.push_back( Scene_polylines_item::Polyline() );
|
||||
new_item->polylines.back().push_back( it->opposite()->vertex()->point() );
|
||||
new_item->polylines.back().push_back( it->vertex()->point() );
|
||||
}
|
||||
if (new_item->polylines.empty())
|
||||
{
|
||||
delete new_item;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_item->setName(tr("Boundary of %1").arg(item->name()));
|
||||
new_item->setColor(Qt::red);
|
||||
scene->addItem(new_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Polyhedron_demo_polyhedron_stitching_plugin::on_actionStitchBorders_triggered()
|
||||
{
|
||||
Scene_interface::Item_id index = scene->mainSelectionIndex();
|
||||
|
||||
Scene_polyhedron_item* item =
|
||||
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
|
||||
|
||||
if(item)
|
||||
{
|
||||
Polyhedron* pMesh = item->polyhedron();
|
||||
CGAL::polyhedron_stitching(*pMesh);
|
||||
scene->itemChanged(item);
|
||||
}
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2(Polyhedron_demo_polyhedron_stitching_plugin, Polyhedron_demo_polyhedron_stitching_plugin)
|
||||
|
||||
#include "Polyhedron_demo_polyhedron_stitching_plugin.moc"
|
||||
Loading…
Reference in New Issue