mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'cgal/releases/CGAL-4.14-branch' into HEAD
This commit is contained in:
commit
41ef56f8ad
|
|
@ -1109,8 +1109,9 @@ public:
|
|||
// triangle which is tangent at its 3 vertices
|
||||
// \todo improve this part which is not robust with a kernel
|
||||
// with inexact constructions.
|
||||
Bounded_side position = inside_tm2(midpoint(get(vpm1, source(h, tm1)),
|
||||
get(vpm1, target(h, tm1)) ));
|
||||
Bounded_side position = inside_tm2(centroid(get(vpm1, source(h, tm1)),
|
||||
get(vpm1, target(h, tm1)),
|
||||
get(vpm1, target(next(h, tm1), tm1)) ));
|
||||
CGAL_assertion( position != ON_BOUNDARY);
|
||||
if ( position == in_tm2 )
|
||||
is_patch_inside_tm2.set(patch_id);
|
||||
|
|
@ -1257,6 +1258,35 @@ public:
|
|||
FaceIdMap,
|
||||
Intersection_edge_map> Patches;
|
||||
|
||||
boost::unordered_set<vertex_descriptor> border_nm_vertices; // only used if used_to_clip_a_surface == true
|
||||
if (used_to_clip_a_surface)
|
||||
{
|
||||
if (!is_tm1_closed)
|
||||
{
|
||||
// \todo Note a loop over vertex_to_node_id1 would be sufficient
|
||||
// if we merge the patch-id of patches to be removed (that way
|
||||
// non-manifold vertices would not be duplicated in interior
|
||||
// vertices of patche)
|
||||
// special code to handle non-manifold vertices on the boundary
|
||||
BOOST_FOREACH (vertex_descriptor vd, vertices(tm1))
|
||||
{
|
||||
boost::optional<halfedge_descriptor> op_h = is_border(vd, tm1);
|
||||
if (op_h == boost::none) continue;
|
||||
halfedge_descriptor h = *op_h;
|
||||
CGAL_assertion( target(h, tm1) == vd);
|
||||
// check if the target of h is a non-manifold vertex
|
||||
halfedge_descriptor nh = prev( opposite(h, tm1), tm1 );
|
||||
while (!is_border( opposite(nh, tm1), tm1 ) )
|
||||
{
|
||||
nh = prev( opposite(nh, tm1), tm1 );
|
||||
}
|
||||
nh = opposite(nh, tm1);
|
||||
if (next(h, tm1) != nh)
|
||||
border_nm_vertices.insert(target(h, tm1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//store the patch description in a container to avoid recomputing it several times
|
||||
Patches patches_of_tm1( tm1, tm1_patch_ids, fids1, intersection_edges1, nb_patches_tm1),
|
||||
patches_of_tm2( tm2, tm2_patch_ids, fids2, intersection_edges2, nb_patches_tm2);
|
||||
|
|
@ -1606,6 +1636,86 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Code dedicated to the handling of non-manifold vertices
|
||||
BOOST_FOREACH(vertex_descriptor vd, border_nm_vertices)
|
||||
{
|
||||
// first check if at least one incident patch will be kept
|
||||
boost::unordered_set<std::size_t> id_p_rm;
|
||||
bool all_removed=true;
|
||||
BOOST_FOREACH(halfedge_descriptor h, halfedges_around_target(vd, tm1))
|
||||
{
|
||||
face_descriptor f = face(h, tm1);
|
||||
if ( f != GT::null_face() )
|
||||
{
|
||||
const std::size_t p_id = tm1_patch_ids[ get(fids1, f) ];
|
||||
if ( patches_to_remove.test(p_id) )
|
||||
id_p_rm.insert(p_id);
|
||||
else
|
||||
all_removed=false;
|
||||
}
|
||||
}
|
||||
if (all_removed)
|
||||
id_p_rm.erase(id_p_rm.begin());
|
||||
// remove the vertex from the interior vertices of patches to be removed
|
||||
BOOST_FOREACH(std::size_t pid, id_p_rm)
|
||||
patches_of_tm1[pid].interior_vertices.erase(vd);
|
||||
|
||||
// we now need to update the next/prev relationship induced by the future removal of patches
|
||||
// that will not be updated after patch removal
|
||||
if (!all_removed && !id_p_rm.empty())
|
||||
{
|
||||
typedef std::pair<halfedge_descriptor, halfedge_descriptor> Hedge_pair;
|
||||
std::vector< Hedge_pair> hedges_to_link;
|
||||
typename CGAL::Halfedge_around_target_iterator<TriangleMesh> hit, end;
|
||||
boost::tie(hit,end) = halfedges_around_target(vd, tm1);
|
||||
for(; hit!=end; ++hit)
|
||||
{
|
||||
// look for a border halfedge incident to the non-manifold vertex that will not be
|
||||
// removed.
|
||||
if ( !is_border(*hit, tm1) ||
|
||||
patches_to_remove.test( tm1_patch_ids[ get(fids1, face(opposite(*hit, tm1), tm1)) ] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// we have to fix only cases when the next halfedge is to be removed
|
||||
halfedge_descriptor nh = next(*hit, tm1);
|
||||
if ( !patches_to_remove.test( tm1_patch_ids[ get(fids1, face(opposite(nh, tm1), tm1)) ] ) )
|
||||
continue;
|
||||
|
||||
halfedge_descriptor h = *hit;
|
||||
// we are now looking for a potential next candidate halfedge
|
||||
do{
|
||||
++hit;
|
||||
if (hit == end) break;
|
||||
if ( is_border(*hit, tm1) )
|
||||
{
|
||||
if ( patches_to_remove.test( tm1_patch_ids[ get(fids1, face(opposite(*hit, tm1), tm1)) ] ) )
|
||||
{
|
||||
// we check if the next halfedge is a good next
|
||||
nh = next(*hit, tm1);
|
||||
if ( !patches_to_remove.test( tm1_patch_ids[ get(fids1, face(opposite(nh, tm1), tm1)) ] ) )
|
||||
{
|
||||
hedges_to_link.push_back( Hedge_pair(h, nh) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we push-back the halfedge for the next round only if it was not the first
|
||||
if (h != *cpp11::prev(hit))
|
||||
--hit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(true);
|
||||
if (hit == end) break;
|
||||
}
|
||||
BOOST_FOREACH ( const Hedge_pair& p, hedges_to_link)
|
||||
set_next(p.first, p.second, tm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define CGAL_COREF_FUNCTION_CALL_DEF(BO_type) \
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
namespace params = PMP::parameters;
|
||||
|
|
@ -283,6 +284,49 @@ void test()
|
|||
assert(is_valid_polygon_mesh(tm1));
|
||||
CGAL::clear(tm1);
|
||||
CGAL::clear(tm2);
|
||||
|
||||
// non-manifold border vertices
|
||||
std::stringstream ss;
|
||||
ss << "OFF\n 5 2 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 0 1 4\n3 1 2 3\n";
|
||||
ss >> tm1;
|
||||
PMP::clip(tm1, K::Plane_3(-1,0,0,2));
|
||||
assert(vertices(tm1).size()==3);
|
||||
CGAL::clear(tm1);
|
||||
|
||||
ss = std::stringstream();
|
||||
ss << "OFF\n 7 4 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 3 5\n";
|
||||
ss >> tm1;
|
||||
CGAL::Euler::remove_face(halfedge(*CGAL::cpp11::prev(faces(tm1).end()),tm1),tm1);
|
||||
PMP::clip(tm1, K::Plane_3(-1,0,0,2));
|
||||
assert(vertices(tm1).size()==6);
|
||||
CGAL::clear(tm1);
|
||||
|
||||
ss = std::stringstream();
|
||||
ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n";
|
||||
ss >> tm1;
|
||||
for (int i=0;i<3;++i)
|
||||
CGAL::Euler::remove_face(halfedge(*CGAL::cpp11::prev(faces(tm1).end()),tm1),tm1);
|
||||
PMP::clip(tm1, K::Plane_3(-1,0,0,2));
|
||||
assert(vertices(tm1).size()==7);
|
||||
CGAL::clear(tm1);
|
||||
|
||||
ss = std::stringstream();
|
||||
ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n";
|
||||
ss >> tm1;
|
||||
for (int i=0;i<3;++i)
|
||||
CGAL::Euler::remove_face(halfedge(*CGAL::cpp11::prev(faces(tm1).end()),tm1),tm1);
|
||||
PMP::clip(tm1, K::Plane_3(0,1,0,0));
|
||||
assert(vertices(tm1).size()==3);
|
||||
CGAL::clear(tm1);
|
||||
|
||||
ss = std::stringstream();
|
||||
ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n";
|
||||
ss >> tm1;
|
||||
for (int i=0;i<3;++i)
|
||||
CGAL::Euler::remove_face(halfedge(*CGAL::cpp11::prev(faces(tm1).end()),tm1),tm1);
|
||||
PMP::clip(tm1, K::Plane_3(0,-1,0,0));
|
||||
assert(vertices(tm1).size()==7);
|
||||
CGAL::clear(tm1);
|
||||
}
|
||||
|
||||
int main()
|
||||
|
|
|
|||
|
|
@ -49,7 +49,13 @@ read_OBJ( std::istream& input,
|
|||
faces.push_back( std::vector<std::size_t>() );
|
||||
while(iss >> i)
|
||||
{
|
||||
faces.back().push_back(i-1);
|
||||
if(i < 1)
|
||||
{
|
||||
faces.back().push_back(points.size()+i);//negative indices are relative references
|
||||
}
|
||||
else {
|
||||
faces.back().push_back(i-1);
|
||||
}
|
||||
iss.ignore(256, ' ');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,34 @@ export INSTALLATION_DIR=""
|
|||
export TESTSUITE_DIR=""
|
||||
USE_LATEST_UNZIPPED=""
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
# Logging functions
|
||||
# ----------------------------------------------------------------------------------------
|
||||
log()
|
||||
{
|
||||
LOGFILE=${1}
|
||||
shift
|
||||
if [ -n "${CONSOLE_OUTPUT}" ]; then
|
||||
printf "${*} ...\n"
|
||||
fi
|
||||
printf "\n-------------------------------------------------------\n" >> "${LOGFILE}"
|
||||
printf " ${*} ...\n" >> "${LOGFILE}"
|
||||
printf "\n-------------------------------------------------------\n" >> "${LOGFILE}"
|
||||
}
|
||||
|
||||
log_done()
|
||||
{
|
||||
if [ -n "${CONSOLE_OUTPUT}" ]; then
|
||||
printf \
|
||||
" done\n-------------------------------------------------------\n"
|
||||
fi
|
||||
printf "\n-------------------------------------------------------\n" >> "${1}"
|
||||
printf " **DONE**\n" >> "${1}"
|
||||
printf "\n-------------------------------------------------------\n" >> "${1}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
# Downloads the file "LATEST" whose contents indicates which release to test
|
||||
# ----------------------------------------------------------------------------------------
|
||||
|
|
@ -202,13 +230,6 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "${SCRIPTS_DIR}" ]; then
|
||||
CGAL_DIR=`readlink "${CGAL_HOME}/CGAL-git"`
|
||||
else
|
||||
CGAL_DIR=`readlink "${CGAL_HOME}/CGAL-I"`
|
||||
fi
|
||||
|
||||
source "${CGAL_DIR}/${SCRIPTS_DIR}developer_scripts/log.sh"
|
||||
LOGS_DIR="${CGAL_HOME}/AUTOTEST_LOGS"
|
||||
LOCK_FILE="${CGAL_HOME}/autotest_cgal_with_cmake.lock"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue