mirror of https://github.com/CGAL/cgal
New normals orientation method:
radial_normals_orientation_3() does a radial orientation of the normals of a point set. Normals are oriented towards exterior of the point set. This very simple and very fast method is intended to convex objects.
This commit is contained in:
parent
be789e8a46
commit
df58e7c4f8
|
|
@ -140,16 +140,19 @@ BEGIN
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
MENUITEM "Orient Normals with Minimum Spanning Tree", ID_ALGORITHMS_ORIENTNORMALSMST
|
MENUITEM "Orient Normals with Minimum Spanning Tree", ID_ALGORITHMS_ORIENTNORMALSMST
|
||||||
MENUITEM "Orient Normals w.r.t. Cameras (Gyroviz)", ID_ALGORITHMS_ORIENTNORMALSCAMERAS
|
MENUITEM "Orient Normals w.r.t. Cameras (Gyroviz)", ID_ALGORITHMS_ORIENTNORMALSCAMERAS
|
||||||
|
MENUITEM "Radial Normals Orientation", ID_RADIAL_NORMALS_ORIENTATION
|
||||||
|
MENUITEM "Flip Normals", ID_FLIP_NORMALS
|
||||||
END
|
END
|
||||||
POPUP "&Reconstruction"
|
POPUP "&Reconstruction"
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "1-step Poisson reconstruction\tP", ID_ONE_STEP_POISSON_RECONSTRUCTION
|
MENUITEM "1-step Poisson reconstruction\tP", ID_ONE_STEP_POISSON_RECONSTRUCTION
|
||||||
MENUITEM "1-step Poisson reconstruction with Normalized Divergence", 32838
|
MENUITEM "1-step Poisson reconstruction with Normalized Divergence", ID_RECONSTRUCTION_ONE_STEP_NORMALIZED
|
||||||
POPUP "Step-by-step Poisson reconstruction"
|
POPUP "Step-by-step Poisson reconstruction"
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "Create Poisson Delaunay Triangulation\t1", ID_CREATE_POISSON_TRIANGULATION
|
MENUITEM "Create Poisson Delaunay Triangulation\t1", ID_CREATE_POISSON_TRIANGULATION
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
MENUITEM "Calculate average spacing", ID_STEP_CALCULATEAVERAGESPACING
|
MENUITEM "Calculate average spacing", ID_STEP_CALCULATEAVERAGESPACING
|
||||||
|
MENUITEM SEPARATOR
|
||||||
MENUITEM "Delaunay refinement\t2", ID_RECONSTRUCTION_DELAUNAYREFINEMENT
|
MENUITEM "Delaunay refinement\t2", ID_RECONSTRUCTION_DELAUNAYREFINEMENT
|
||||||
MENUITEM "Delaunay refinement in shell", ID_ALGORITHMS_REFINEINSHELL
|
MENUITEM "Delaunay refinement in shell", ID_ALGORITHMS_REFINEINSHELL
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
|
|
@ -157,9 +160,9 @@ BEGIN
|
||||||
MENUITEM "Extrapolate Normals using gaussian kernels", ID_STEP_EXTRAPOLATENORMALSUSINGGAUSSIANKERNELS
|
MENUITEM "Extrapolate Normals using gaussian kernels", ID_STEP_EXTRAPOLATENORMALSUSINGGAUSSIANKERNELS
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
MENUITEM "Solve Poisson Equation\t4", ID_RECONSTRUCTION_POISSON
|
MENUITEM "Solve Poisson Equation\t4", ID_RECONSTRUCTION_POISSON
|
||||||
MENUITEM "Solve Poisson Equation With normalized Divergence", ID_RECONSTRUCTION_POISSON_NORMALIZED
|
MENUITEM "Solve Poisson Equation With Normalized Divergence", ID_RECONSTRUCTION_POISSON_NORMALIZED
|
||||||
MENUITEM SEPARATOR
|
|
||||||
MENUITEM "Poisson Statistics", ID_ALGORITHMS_POISSONSTATISTICS
|
MENUITEM "Poisson Statistics", ID_ALGORITHMS_POISSONSTATISTICS
|
||||||
|
MENUITEM SEPARATOR
|
||||||
MENUITEM "Surface Meshing\t5", ID_RECONSTRUCTION_POISSON_SURFACE_MESHING
|
MENUITEM "Surface Meshing\t5", ID_RECONSTRUCTION_POISSON_SURFACE_MESHING
|
||||||
MENUITEM "Marching Tet Contouring\t6", ID_ALGORITHMS_MARCHINGTETCONTOURING
|
MENUITEM "Marching Tet Contouring\t6", ID_ALGORITHMS_MARCHINGTETCONTOURING
|
||||||
END
|
END
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include <CGAL/average_spacing_3.h>
|
#include <CGAL/average_spacing_3.h>
|
||||||
#include <CGAL/merge_epsilon_nearest_points_3.h>
|
#include <CGAL/merge_epsilon_nearest_points_3.h>
|
||||||
#include <CGAL/random_simplification_points_3.h>
|
#include <CGAL/random_simplification_points_3.h>
|
||||||
|
#include <CGAL/radial_normals_orientation_3.h>
|
||||||
#include <CGAL/Peak_memory_sizer.h>
|
#include <CGAL/Peak_memory_sizer.h>
|
||||||
#include <CGAL/surface_reconstruction_assertions.h>
|
#include <CGAL/surface_reconstruction_assertions.h>
|
||||||
|
|
||||||
|
|
@ -77,6 +78,7 @@ BEGIN_MESSAGE_MAP(CPoissonDoc, CDocument)
|
||||||
ON_COMMAND(ID_RECONSTRUCTION_DELAUNAYREFINEMENT, OnReconstructionDelaunayRefinement)
|
ON_COMMAND(ID_RECONSTRUCTION_DELAUNAYREFINEMENT, OnReconstructionDelaunayRefinement)
|
||||||
ON_COMMAND(ID_RECONSTRUCTION_POISSON, OnReconstructionPoisson)
|
ON_COMMAND(ID_RECONSTRUCTION_POISSON, OnReconstructionPoisson)
|
||||||
ON_COMMAND(ID_RECONSTRUCTION_POISSON_NORMALIZED, OnReconstructionPoissonNormalized)
|
ON_COMMAND(ID_RECONSTRUCTION_POISSON_NORMALIZED, OnReconstructionPoissonNormalized)
|
||||||
|
ON_UPDATE_COMMAND_UI(ID_RECONSTRUCTION_POISSON_NORMALIZED, OnUpdateReconstructionPoissonNormalized)
|
||||||
ON_COMMAND(ID_ALGORITHMS_REFINEINSHELL, OnAlgorithmsRefineInShell)
|
ON_COMMAND(ID_ALGORITHMS_REFINEINSHELL, OnAlgorithmsRefineInShell)
|
||||||
ON_COMMAND(ID_RECONSTRUCTION_POISSON_SURFACE_MESHING, OnReconstructionPoissonSurfaceMeshing)
|
ON_COMMAND(ID_RECONSTRUCTION_POISSON_SURFACE_MESHING, OnReconstructionPoissonSurfaceMeshing)
|
||||||
ON_UPDATE_COMMAND_UI(ID_RECONSTRUCTION_POISSON, OnUpdateReconstructionPoisson)
|
ON_UPDATE_COMMAND_UI(ID_RECONSTRUCTION_POISSON, OnUpdateReconstructionPoisson)
|
||||||
|
|
@ -110,21 +112,28 @@ BEGIN_MESSAGE_MAP(CPoissonDoc, CDocument)
|
||||||
ON_COMMAND(ID_ALGORITHMS_OUTLIERS_REMOVAL_WRT_AVG_KNN_SQ_DIST, OnOutliersRemovalWrtAvgKnnSqDist)
|
ON_COMMAND(ID_ALGORITHMS_OUTLIERS_REMOVAL_WRT_AVG_KNN_SQ_DIST, OnOutliersRemovalWrtAvgKnnSqDist)
|
||||||
ON_UPDATE_COMMAND_UI(ID_ALGORITHMS_OUTLIERS_REMOVAL_WRT_AVG_KNN_SQ_DIST, OnUpdateOutliersRemovalWrtAvgKnnSqDist)
|
ON_UPDATE_COMMAND_UI(ID_ALGORITHMS_OUTLIERS_REMOVAL_WRT_AVG_KNN_SQ_DIST, OnUpdateOutliersRemovalWrtAvgKnnSqDist)
|
||||||
ON_COMMAND(ID_ANALYSIS_AVERAGE_SPACING, OnAnalysisAverageSpacing)
|
ON_COMMAND(ID_ANALYSIS_AVERAGE_SPACING, OnAnalysisAverageSpacing)
|
||||||
ON_COMMAND(ID_ONE_STEP_POISSON_RECONSTRUCTION, OnOneStepPoissonReconstruction)
|
|
||||||
ON_COMMAND(ID_RECONSTRUCTION_ONE_STEP_NORMALIZED, OnOneStepPoissonReconstructionWithNormalizedDivergence)
|
|
||||||
ON_UPDATE_COMMAND_UI(ID_ONE_STEP_POISSON_RECONSTRUCTION, OnUpdateOneStepPoissonReconstruction)
|
|
||||||
ON_UPDATE_COMMAND_UI(ID_ANALYSIS_AVERAGE_SPACING, OnUpdateAnalysisAverageSpacing)
|
ON_UPDATE_COMMAND_UI(ID_ANALYSIS_AVERAGE_SPACING, OnUpdateAnalysisAverageSpacing)
|
||||||
|
ON_COMMAND(ID_ONE_STEP_POISSON_RECONSTRUCTION, OnOneStepPoissonReconstruction)
|
||||||
|
ON_UPDATE_COMMAND_UI(ID_ONE_STEP_POISSON_RECONSTRUCTION, OnUpdateOneStepPoissonReconstruction)
|
||||||
|
ON_COMMAND(ID_RECONSTRUCTION_ONE_STEP_NORMALIZED, OnOneStepPoissonReconstructionWithNormalizedDivergence)
|
||||||
ON_COMMAND(ID_RECONSTRUCTION_APSS_RECONSTRUCTION, OnReconstructionApssReconstruction)
|
ON_COMMAND(ID_RECONSTRUCTION_APSS_RECONSTRUCTION, OnReconstructionApssReconstruction)
|
||||||
ON_UPDATE_COMMAND_UI(ID_RECONSTRUCTION_APSS_RECONSTRUCTION, OnUpdateReconstructionApssReconstruction)
|
ON_UPDATE_COMMAND_UI(ID_RECONSTRUCTION_APSS_RECONSTRUCTION, OnUpdateReconstructionApssReconstruction)
|
||||||
ON_COMMAND(ID_MODE_APSS, OnModeAPSS)
|
ON_COMMAND(ID_MODE_APSS, OnModeAPSS)
|
||||||
ON_UPDATE_COMMAND_UI(ID_MODE_APSS, OnUpdateModeAPSS)
|
ON_UPDATE_COMMAND_UI(ID_MODE_APSS, OnUpdateModeAPSS)
|
||||||
ON_COMMAND(ID_RECONSTRUCTION_SAVEAS, &CPoissonDoc::OnReconstructionSaveas)
|
ON_COMMAND(ID_RECONSTRUCTION_SAVEAS, OnReconstructionSaveas)
|
||||||
ON_COMMAND(ID_STEP_CALCULATEAVERAGESPACING, OnCalculateAverageSpacing)
|
ON_COMMAND(ID_STEP_CALCULATEAVERAGESPACING, OnCalculateAverageSpacing)
|
||||||
ON_COMMAND(ID_STEP_EXTRAPOLATENORMALSUSINGGAUSSIANKERNELS,OnExtrapolateNormalsUsingGaussianKernel)
|
ON_COMMAND(ID_STEP_EXTRAPOLATENORMALSUSINGGAUSSIANKERNELS,OnExtrapolateNormalsUsingGaussianKernel)
|
||||||
ON_COMMAND(ID_POINT_CLOUD_SIMPLIFICATION_BY_CLUSTERING, &CPoissonDoc::OnPointCloudSimplificationByClustering)
|
ON_UPDATE_COMMAND_UI(ID_STEP_EXTRAPOLATENORMALSUSINGGAUSSIANKERNELS, OnUpdateStepExtrapolatenormalsusinggaussiankernels)
|
||||||
ON_UPDATE_COMMAND_UI(ID_POINT_CLOUD_SIMPLIFICATION_BY_CLUSTERING, &CPoissonDoc::OnUpdatePointCloudSimplificationByClustering)
|
ON_COMMAND(ID_POINT_CLOUD_SIMPLIFICATION_BY_CLUSTERING, OnPointCloudSimplificationByClustering)
|
||||||
ON_COMMAND(ID_POINT_CLOUD_SIMPLIFICATION_RANDOM, &CPoissonDoc::OnPointCloudSimplificationRandom)
|
ON_UPDATE_COMMAND_UI(ID_POINT_CLOUD_SIMPLIFICATION_BY_CLUSTERING, OnUpdatePointCloudSimplificationByClustering)
|
||||||
ON_UPDATE_COMMAND_UI(ID_POINT_CLOUD_SIMPLIFICATION_RANDOM, &CPoissonDoc::OnUpdatePointCloudSimplificationRandom)
|
ON_COMMAND(ID_POINT_CLOUD_SIMPLIFICATION_RANDOM, OnPointCloudSimplificationRandom)
|
||||||
|
ON_UPDATE_COMMAND_UI(ID_POINT_CLOUD_SIMPLIFICATION_RANDOM, OnUpdatePointCloudSimplificationRandom)
|
||||||
|
ON_COMMAND(ID_RADIAL_NORMALS_ORIENTATION, OnRadialNormalsOrientation)
|
||||||
|
ON_UPDATE_COMMAND_UI(ID_RADIAL_NORMALS_ORIENTATION, OnUpdateRadialNormalsOrientation)
|
||||||
|
ON_COMMAND(ID_FLIP_NORMALS, OnFlipNormals)
|
||||||
|
ON_UPDATE_COMMAND_UI(ID_FLIP_NORMALS, OnUpdateFlipNormals)
|
||||||
|
ON_UPDATE_COMMAND_UI(ID_RECONSTRUCTION_ONE_STEP_NORMALIZED, &CPoissonDoc::OnUpdateReconstructionOneStepNormalized)
|
||||||
|
ON_UPDATE_COMMAND_UI(ID_STEP_CALCULATEAVERAGESPACING, &CPoissonDoc::OnUpdateStepCalculateaveragespacing)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -374,6 +383,10 @@ void CPoissonDoc::OnFileSaveAs()
|
||||||
path = path.Left(path.ReverseFind('\\'));
|
path = path.Left(path.ReverseFind('\\'));
|
||||||
SetCurrentDirectory(path);
|
SetCurrentDirectory(path);
|
||||||
|
|
||||||
|
// Save normals?
|
||||||
|
assert(m_points.begin() != m_points.end());
|
||||||
|
bool points_have_normals = (m_points.begin()->normal() != CGAL::NULL_VECTOR);
|
||||||
|
|
||||||
// if .pwn extension
|
// if .pwn extension
|
||||||
if(extension.CompareNoCase(".pwn") == 0)
|
if(extension.CompareNoCase(".pwn") == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -388,7 +401,8 @@ void CPoissonDoc::OnFileSaveAs()
|
||||||
else if(extension.CompareNoCase(".xyz") == 0)
|
else if(extension.CompareNoCase(".xyz") == 0)
|
||||||
{
|
{
|
||||||
if( ! CGAL::surface_reconstruction_write_xyz(dlgExport.m_ofn.lpstrFile,
|
if( ! CGAL::surface_reconstruction_write_xyz(dlgExport.m_ofn.lpstrFile,
|
||||||
m_points.begin(), m_points.end()) )
|
m_points.begin(), m_points.end(),
|
||||||
|
points_have_normals) )
|
||||||
{
|
{
|
||||||
prompt_message("Unable to save file");
|
prompt_message("Unable to save file");
|
||||||
return;
|
return;
|
||||||
|
|
@ -867,6 +881,12 @@ void CPoissonDoc::OnReconstructionPoisson()
|
||||||
EndWaitCursor();
|
EndWaitCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable "Solve Poisson equation" if Delaunay refinement is applied
|
||||||
|
void CPoissonDoc::OnUpdateReconstructionPoisson(CCmdUI *pCmdUI)
|
||||||
|
{
|
||||||
|
pCmdUI->Enable(m_edit_mode == POISSON && m_triangulation_refined);
|
||||||
|
}
|
||||||
|
|
||||||
void CPoissonDoc::OnReconstructionPoissonNormalized()
|
void CPoissonDoc::OnReconstructionPoissonNormalized()
|
||||||
{
|
{
|
||||||
assert(m_poisson_dt != NULL);
|
assert(m_poisson_dt != NULL);
|
||||||
|
|
@ -897,8 +917,7 @@ void CPoissonDoc::OnReconstructionPoissonNormalized()
|
||||||
EndWaitCursor();
|
EndWaitCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable "Solve Poisson equation" if Delaunay refinement is applied
|
void CPoissonDoc::OnUpdateReconstructionPoissonNormalized(CCmdUI *pCmdUI)
|
||||||
void CPoissonDoc::OnUpdateReconstructionPoisson(CCmdUI *pCmdUI)
|
|
||||||
{
|
{
|
||||||
pCmdUI->Enable(m_edit_mode == POISSON && m_triangulation_refined);
|
pCmdUI->Enable(m_edit_mode == POISSON && m_triangulation_refined);
|
||||||
}
|
}
|
||||||
|
|
@ -954,10 +973,10 @@ void CPoissonDoc::OnReconstructionPoissonSurfaceMeshing()
|
||||||
<< " angle="<<m_sm_angle << " degrees,\n"
|
<< " angle="<<m_sm_angle << " degrees,\n"
|
||||||
<< " radius="<<m_sm_radius<<" * p.s.r.,\n"
|
<< " radius="<<m_sm_radius<<" * p.s.r.,\n"
|
||||||
<< " distance="<<m_sm_distance_poisson<<" * p.s.r.,\n"
|
<< " distance="<<m_sm_distance_poisson<<" * p.s.r.,\n"
|
||||||
<< " Manifold_tag)\n";
|
<< " Manifold_with_boundary_tag)\n";
|
||||||
|
|
||||||
// meshing surface
|
// meshing surface
|
||||||
CGAL::make_surface_mesh(m_surface_mesher_c2t3, surface, criteria, CGAL::Manifold_tag());
|
CGAL::make_surface_mesh(m_surface_mesher_c2t3, surface, criteria, CGAL::Manifold_with_boundary_tag());
|
||||||
|
|
||||||
// get output surface
|
// get output surface
|
||||||
std::deque<Triangle> triangles;
|
std::deque<Triangle> triangles;
|
||||||
|
|
@ -1148,7 +1167,9 @@ void CPoissonDoc::OnOneStepPoissonReconstructionWithNormalizedDivergence()
|
||||||
//OnCalculateAverageSpacing();
|
//OnCalculateAverageSpacing();
|
||||||
OnReconstructionDelaunayRefinement();
|
OnReconstructionDelaunayRefinement();
|
||||||
//OnExtrapolateNormalsUsingGaussianKernel(); // TO TEST
|
//OnExtrapolateNormalsUsingGaussianKernel(); // TO TEST
|
||||||
|
if (m_triangulation_refined)
|
||||||
OnReconstructionPoissonNormalized();
|
OnReconstructionPoissonNormalized();
|
||||||
|
if (m_poisson_solved)
|
||||||
OnReconstructionPoissonSurfaceMeshing();
|
OnReconstructionPoissonSurfaceMeshing();
|
||||||
|
|
||||||
status_message("1-step Poisson reconstruction with normalized divergence...done (%.2lf s)", task_timer.time());
|
status_message("1-step Poisson reconstruction with normalized divergence...done (%.2lf s)", task_timer.time());
|
||||||
|
|
@ -1157,6 +1178,11 @@ void CPoissonDoc::OnOneStepPoissonReconstructionWithNormalizedDivergence()
|
||||||
EndWaitCursor();
|
EndWaitCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPoissonDoc::OnUpdateReconstructionOneStepNormalized(CCmdUI *pCmdUI)
|
||||||
|
{
|
||||||
|
OnUpdateCreatePoissonTriangulation(pCmdUI);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove vertices / cameras cone's angle is low
|
// Remove vertices / cameras cone's angle is low
|
||||||
void CPoissonDoc::OnAlgorithmsOutliersRemovalWrtCamerasConeAngle()
|
void CPoissonDoc::OnAlgorithmsOutliersRemovalWrtCamerasConeAngle()
|
||||||
{
|
{
|
||||||
|
|
@ -1165,6 +1191,7 @@ void CPoissonDoc::OnAlgorithmsOutliersRemovalWrtCamerasConeAngle()
|
||||||
CGAL::Timer task_timer; task_timer.start();
|
CGAL::Timer task_timer; task_timer.start();
|
||||||
|
|
||||||
// Select points to delete
|
// Select points to delete
|
||||||
|
m_points.select(m_points.begin(), m_points.end(), false);
|
||||||
Point_set::iterator first_iterator_to_remove =
|
Point_set::iterator first_iterator_to_remove =
|
||||||
remove_outliers_wrt_camera_cone_angle_3(
|
remove_outliers_wrt_camera_cone_angle_3(
|
||||||
m_points.begin(), m_points.end(),
|
m_points.begin(), m_points.end(),
|
||||||
|
|
@ -1194,6 +1221,7 @@ void CPoissonDoc::OnOutliersRemovalWrtAvgKnnSqDist()
|
||||||
CGAL::Timer task_timer; task_timer.start();
|
CGAL::Timer task_timer; task_timer.start();
|
||||||
|
|
||||||
// Select points to delete
|
// Select points to delete
|
||||||
|
m_points.select(m_points.begin(), m_points.end(), false);
|
||||||
Point_set::iterator first_iterator_to_remove =
|
Point_set::iterator first_iterator_to_remove =
|
||||||
CGAL::remove_outliers_wrt_avg_knn_sq_distance_3(
|
CGAL::remove_outliers_wrt_avg_knn_sq_distance_3(
|
||||||
m_points.begin(), m_points.end(),
|
m_points.begin(), m_points.end(),
|
||||||
|
|
@ -1284,10 +1312,10 @@ void CPoissonDoc::OnReconstructionApssReconstruction()
|
||||||
<< " angle="<<m_sm_angle << " degrees,\n"
|
<< " angle="<<m_sm_angle << " degrees,\n"
|
||||||
<< " radius="<<m_sm_radius<<" * p.s.r.,\n"
|
<< " radius="<<m_sm_radius<<" * p.s.r.,\n"
|
||||||
<< " distance="<<m_sm_distance_apss<<" * p.s.r.,\n"
|
<< " distance="<<m_sm_distance_apss<<" * p.s.r.,\n"
|
||||||
<< " Manifold_tag)\n";
|
<< " Manifold_with_boundary_tag)\n";
|
||||||
|
|
||||||
// meshing surface
|
// meshing surface
|
||||||
CGAL::make_surface_mesh(m_surface_mesher_c2t3, surface, criteria, CGAL::Manifold_tag());
|
CGAL::make_surface_mesh(m_surface_mesher_c2t3, surface, criteria, CGAL::Manifold_with_boundary_tag());
|
||||||
|
|
||||||
// get output surface
|
// get output surface
|
||||||
std::deque<Triangle> triangles;
|
std::deque<Triangle> triangles;
|
||||||
|
|
@ -1342,12 +1370,18 @@ void CPoissonDoc::OnCalculateAverageSpacing()
|
||||||
|
|
||||||
Point_set output;
|
Point_set output;
|
||||||
m_poisson_function->average_spacing_avg_knn_sq_distance_3();
|
m_poisson_function->average_spacing_avg_knn_sq_distance_3();
|
||||||
|
|
||||||
status_message("Average spacing calculated...took %f seconds", task_timer.time());
|
status_message("Average spacing calculated...took %f seconds", task_timer.time());
|
||||||
update_status();
|
update_status();
|
||||||
UpdateAllViews(NULL);
|
UpdateAllViews(NULL);
|
||||||
EndWaitCursor();
|
EndWaitCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPoissonDoc::OnUpdateStepCalculateaveragespacing(CCmdUI *pCmdUI)
|
||||||
|
{
|
||||||
|
pCmdUI->Enable(m_edit_mode == POISSON);
|
||||||
|
}
|
||||||
|
|
||||||
void CPoissonDoc::OnExtrapolateNormalsUsingGaussianKernel()
|
void CPoissonDoc::OnExtrapolateNormalsUsingGaussianKernel()
|
||||||
{
|
{
|
||||||
BeginWaitCursor();
|
BeginWaitCursor();
|
||||||
|
|
@ -1355,13 +1389,18 @@ void CPoissonDoc::OnExtrapolateNormalsUsingGaussianKernel()
|
||||||
CGAL::Timer task_timer; task_timer.start();
|
CGAL::Timer task_timer; task_timer.start();
|
||||||
|
|
||||||
int a = m_poisson_function->extrapolate_normals_using_gaussian_kernel();
|
int a = m_poisson_function->extrapolate_normals_using_gaussian_kernel();
|
||||||
status_message("Extrapolation of normals done... %d normals inserted",a);
|
|
||||||
|
|
||||||
|
status_message("Extrapolation of normals done... %d normals inserted",a);
|
||||||
update_status();
|
update_status();
|
||||||
UpdateAllViews(NULL);
|
UpdateAllViews(NULL);
|
||||||
EndWaitCursor();
|
EndWaitCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPoissonDoc::OnUpdateStepExtrapolatenormalsusinggaussiankernels(CCmdUI *pCmdUI)
|
||||||
|
{
|
||||||
|
pCmdUI->Enable(m_edit_mode == POISSON && m_triangulation_refined);
|
||||||
|
}
|
||||||
|
|
||||||
void CPoissonDoc::OnEditDelete()
|
void CPoissonDoc::OnEditDelete()
|
||||||
{
|
{
|
||||||
BeginWaitCursor();
|
BeginWaitCursor();
|
||||||
|
|
@ -1407,6 +1446,7 @@ void CPoissonDoc::OnPointCloudSimplificationByClustering()
|
||||||
FT size = sqrt(bounding_sphere.squared_radius());
|
FT size = sqrt(bounding_sphere.squared_radius());
|
||||||
|
|
||||||
// Select points to delete
|
// Select points to delete
|
||||||
|
m_points.select(m_points.begin(), m_points.end(), false);
|
||||||
Point_set::iterator first_iterator_to_remove =
|
Point_set::iterator first_iterator_to_remove =
|
||||||
CGAL::merge_epsilon_nearest_points_3(
|
CGAL::merge_epsilon_nearest_points_3(
|
||||||
m_points.begin(), m_points.end(),
|
m_points.begin(), m_points.end(),
|
||||||
|
|
@ -1431,6 +1471,7 @@ void CPoissonDoc::OnPointCloudSimplificationRandom()
|
||||||
CGAL::Timer task_timer; task_timer.start();
|
CGAL::Timer task_timer; task_timer.start();
|
||||||
|
|
||||||
// Select points to delete
|
// Select points to delete
|
||||||
|
m_points.select(m_points.begin(), m_points.end(), false);
|
||||||
Point_set::iterator first_iterator_to_remove =
|
Point_set::iterator first_iterator_to_remove =
|
||||||
CGAL::random_simplification_points_3(
|
CGAL::random_simplification_points_3(
|
||||||
m_points.begin(), m_points.end(),
|
m_points.begin(), m_points.end(),
|
||||||
|
|
@ -1447,3 +1488,57 @@ void CPoissonDoc::OnUpdatePointCloudSimplificationRandom(CCmdUI *pCmdUI)
|
||||||
{
|
{
|
||||||
pCmdUI->Enable(m_edit_mode == POINT_SET);
|
pCmdUI->Enable(m_edit_mode == POINT_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPoissonDoc::OnRadialNormalsOrientation()
|
||||||
|
{
|
||||||
|
BeginWaitCursor();
|
||||||
|
status_message("Radial Normals Orientation...");
|
||||||
|
CGAL::Timer task_timer; task_timer.start();
|
||||||
|
|
||||||
|
CGAL::radial_normals_orientation_3(m_points.begin(), m_points.end(),
|
||||||
|
get(boost::vertex_index, m_points),
|
||||||
|
get(CGAL::vertex_point, m_points),
|
||||||
|
get(boost::vertex_normal, m_points));
|
||||||
|
|
||||||
|
// Select non-oriented normals
|
||||||
|
m_points.select(m_points.begin(), m_points.end(), false);
|
||||||
|
for (int i=0; i<m_points.size(); i++)
|
||||||
|
if ( ! m_points[i].normal().is_oriented() )
|
||||||
|
m_points.select(&m_points[i]);
|
||||||
|
|
||||||
|
status_message("Radial Normals Orientation...done (%.2lf s)", task_timer.time());
|
||||||
|
update_status();
|
||||||
|
UpdateAllViews(NULL);
|
||||||
|
EndWaitCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPoissonDoc::OnUpdateRadialNormalsOrientation(CCmdUI *pCmdUI)
|
||||||
|
{
|
||||||
|
assert(m_points.begin() != m_points.end());
|
||||||
|
bool points_have_normals = (m_points.begin()->normal() != CGAL::NULL_VECTOR);
|
||||||
|
pCmdUI->Enable(m_edit_mode == POINT_SET && points_have_normals);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPoissonDoc::OnFlipNormals()
|
||||||
|
{
|
||||||
|
BeginWaitCursor();
|
||||||
|
status_message("Flip Normals...");
|
||||||
|
CGAL::Timer task_timer; task_timer.start();
|
||||||
|
|
||||||
|
// Flip normals
|
||||||
|
for (int i=0; i<m_points.size(); i++)
|
||||||
|
m_points[i].normal() = Normal(-m_points[i].normal().get_vector(),
|
||||||
|
m_points[i].normal().is_oriented());
|
||||||
|
|
||||||
|
status_message("Flip Normals...done (%.2lf s)", task_timer.time());
|
||||||
|
update_status();
|
||||||
|
UpdateAllViews(NULL);
|
||||||
|
EndWaitCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPoissonDoc::OnUpdateFlipNormals(CCmdUI *pCmdUI)
|
||||||
|
{
|
||||||
|
assert(m_points.begin() != m_points.end());
|
||||||
|
bool points_have_normals = (m_points.begin()->normal() != CGAL::NULL_VECTOR);
|
||||||
|
pCmdUI->Enable(m_edit_mode == POINT_SET && points_have_normals);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,14 @@ public:
|
||||||
afx_msg void OnPointCloudSimplificationRandom();
|
afx_msg void OnPointCloudSimplificationRandom();
|
||||||
afx_msg void OnUpdatePointCloudSimplificationByClustering(CCmdUI *pCmdUI);
|
afx_msg void OnUpdatePointCloudSimplificationByClustering(CCmdUI *pCmdUI);
|
||||||
afx_msg void OnUpdatePointCloudSimplificationRandom(CCmdUI *pCmdUI);
|
afx_msg void OnUpdatePointCloudSimplificationRandom(CCmdUI *pCmdUI);
|
||||||
|
afx_msg void OnRadialNormalsOrientation();
|
||||||
|
afx_msg void OnUpdateRadialNormalsOrientation(CCmdUI *pCmdUI);
|
||||||
|
afx_msg void OnFlipNormals();
|
||||||
|
afx_msg void OnUpdateFlipNormals(CCmdUI *pCmdUI);
|
||||||
|
afx_msg void OnUpdateStepExtrapolatenormalsusinggaussiankernels(CCmdUI *pCmdUI);
|
||||||
|
afx_msg void OnUpdateReconstructionPoissonNormalized(CCmdUI *pCmdUI);
|
||||||
|
afx_msg void OnUpdateReconstructionOneStepNormalized(CCmdUI *pCmdUI);
|
||||||
|
afx_msg void OnUpdateStepCalculateaveragespacing(CCmdUI *pCmdUI);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -444,6 +444,10 @@
|
||||||
RelativePath="..\..\..\include\CGAL\poisson_refinement_3.h"
|
RelativePath="..\..\..\include\CGAL\poisson_refinement_3.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\include\CGAL\radial_normals_orientation_3.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\include\CGAL\Random_access_container_index_pmap.h"
|
RelativePath="..\..\..\include\CGAL\Random_access_container_index_pmap.h"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -73,13 +73,17 @@
|
||||||
#define ID_POINT_CLOUD_SIMPLIFICATION_RANDOM 32845
|
#define ID_POINT_CLOUD_SIMPLIFICATION_RANDOM 32845
|
||||||
#define ID_EDIT_DELETE 32867
|
#define ID_EDIT_DELETE 32867
|
||||||
#define ID_EDIT_RESET_SELECTION 32869
|
#define ID_EDIT_RESET_SELECTION 32869
|
||||||
|
#define ID_PROCESSING_RADIALNORMALSORIENTATION 32870
|
||||||
|
#define ID_RADIAL_NORMALS_ORIENTATION 32871
|
||||||
|
#define ID_PROCESSING_FLIPNORMALS 32872
|
||||||
|
#define ID_FLIP_NORMALS 32873
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 134
|
#define _APS_NEXT_RESOURCE_VALUE 134
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32870
|
#define _APS_NEXT_COMMAND_VALUE 32874
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1015
|
#define _APS_NEXT_CONTROL_VALUE 1015
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -272,10 +272,10 @@ int main(int argc, char * argv[])
|
||||||
<< " angle="<<sm_angle << " degrees,\n"
|
<< " angle="<<sm_angle << " degrees,\n"
|
||||||
<< " radius="<<sm_radius<<" * p.s.r.,\n"
|
<< " radius="<<sm_radius<<" * p.s.r.,\n"
|
||||||
<< " distance="<<sm_distance<<" * p.s.r.,\n"
|
<< " distance="<<sm_distance<<" * p.s.r.,\n"
|
||||||
<< " Manifold_tag)\n";
|
<< " Manifold_with_boundary_tag)\n";
|
||||||
|
|
||||||
// meshing surface
|
// meshing surface
|
||||||
CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Manifold_tag());
|
CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Manifold_with_boundary_tag());
|
||||||
|
|
||||||
// Print status
|
// Print status
|
||||||
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
||||||
|
|
|
||||||
|
|
@ -286,10 +286,10 @@ int main(int argc, char * argv[])
|
||||||
<< " angle="<<sm_angle << " degrees,\n"
|
<< " angle="<<sm_angle << " degrees,\n"
|
||||||
<< " radius="<<sm_radius<<" * p.s.r.,\n"
|
<< " radius="<<sm_radius<<" * p.s.r.,\n"
|
||||||
<< " distance="<<sm_distance<<" * p.s.r.,\n"
|
<< " distance="<<sm_distance<<" * p.s.r.,\n"
|
||||||
<< " Manifold_tag)\n";
|
<< " Manifold_with_boundary_tag)\n";
|
||||||
|
|
||||||
// meshing surface
|
// meshing surface
|
||||||
CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Manifold_tag());
|
CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Manifold_with_boundary_tag());
|
||||||
|
|
||||||
// Print status
|
// Print status
|
||||||
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ public:
|
||||||
FT& f() { return m_f; }
|
FT& f() { return m_f; }
|
||||||
|
|
||||||
|
|
||||||
/// Get/set the value of the implicit function.
|
/// Get/set average spacing at each input point.
|
||||||
double average_spacing() const { return m_average_spacing; }
|
double average_spacing() const { return m_average_spacing; }
|
||||||
double& average_spacing() { return m_average_spacing; }
|
double& average_spacing() { return m_average_spacing; }
|
||||||
|
|
||||||
|
|
@ -585,8 +585,8 @@ private:
|
||||||
FT xmin,xmax,ymin,ymax,zmin,zmax; // for all points
|
FT xmin,xmax,ymin,ymax,zmin,zmax; // for all points
|
||||||
xmin = ymin = zmin = 1e38;
|
xmin = ymin = zmin = 1e38;
|
||||||
xmax = ymax = zmax = -1e38;
|
xmax = ymax = zmax = -1e38;
|
||||||
Vector v = CGAL::NULL_VECTOR;
|
Vector sum = CGAL::NULL_VECTOR;
|
||||||
FT norm = 0;
|
FT nb_points = 0;
|
||||||
FT input_xmin,input_xmax,input_ymin,input_ymax,input_zmin,input_zmax; // for INPUT points
|
FT input_xmin,input_xmax,input_ymin,input_ymax,input_zmin,input_zmax; // for INPUT points
|
||||||
input_xmin = input_ymin = input_zmin = 1e38;
|
input_xmin = input_ymin = input_zmin = 1e38;
|
||||||
input_xmax = input_ymax = input_zmax = -1e38;
|
input_xmax = input_ymax = input_zmax = -1e38;
|
||||||
|
|
@ -614,14 +614,14 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// update barycenter of all points
|
// update barycenter of all points
|
||||||
v = v + (p - CGAL::ORIGIN);
|
sum = sum + (p - CGAL::ORIGIN);
|
||||||
norm += 1;
|
nb_points += 1;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
Point p(xmin,ymin,zmin); // for all points
|
Point p(xmin,ymin,zmin); // for all points
|
||||||
Point q(xmax,ymax,zmax);
|
Point q(xmax,ymax,zmax);
|
||||||
m_bounding_box = Iso_cuboid(p,q);
|
m_bounding_box = Iso_cuboid(p,q);
|
||||||
m_barycenter = CGAL::ORIGIN + v / norm;
|
m_barycenter = CGAL::ORIGIN + sum / nb_points;
|
||||||
//
|
//
|
||||||
Point input_p(input_xmin,input_ymin,input_zmin); // for INPUT points
|
Point input_p(input_xmin,input_ymin,input_zmin); // for INPUT points
|
||||||
Point input_q(input_xmax,input_ymax,input_zmax);
|
Point input_q(input_xmax,input_ymax,input_zmax);
|
||||||
|
|
|
||||||
|
|
@ -346,63 +346,20 @@ public:
|
||||||
void average_spacing_avg_knn_sq_distance_3()
|
void average_spacing_avg_knn_sq_distance_3()
|
||||||
{
|
{
|
||||||
Finite_vertices_iterator v;
|
Finite_vertices_iterator v;
|
||||||
int number_vertices = 0;
|
for(v = m_dt.finite_vertices_begin(); v != m_dt.finite_vertices_end(); v++)
|
||||||
for(v = m_dt.finite_vertices_begin();
|
|
||||||
v != m_dt.finite_vertices_end();
|
|
||||||
v++)
|
|
||||||
number_vertices++;
|
|
||||||
|
|
||||||
for(v = m_dt.finite_vertices_begin();
|
|
||||||
v != m_dt.finite_vertices_end();
|
|
||||||
v++)
|
|
||||||
{
|
{
|
||||||
FT sq_distance = 0.0;
|
FT sq_distance = 0.0;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
// std::stack<Vertex_handle> vertices; // use to walk in 3D Delaunay
|
|
||||||
// vertices.push(v);
|
|
||||||
std::vector<Vertex_handle> v_neighbors;
|
std::vector<Vertex_handle> v_neighbors;
|
||||||
m_dt.incident_vertices(v,std::back_inserter(v_neighbors));
|
m_dt.incident_vertices(v,std::back_inserter(v_neighbors));
|
||||||
typename std::vector<Vertex_handle>::iterator it;
|
typename std::vector<Vertex_handle>::iterator it;
|
||||||
for(it = v_neighbors.begin();
|
for(it = v_neighbors.begin(); it != v_neighbors.end(); it++)
|
||||||
it != v_neighbors.end();
|
|
||||||
it++)
|
|
||||||
{
|
{
|
||||||
sq_distance = sq_distance + distance(*it,v)*distance(*it,v);
|
sq_distance = sq_distance + distance(*it,v)*distance(*it,v);
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*while(!vertices.empty() && counter < 0.001 * number_vertices )
|
|
||||||
{
|
|
||||||
Vertex_handle v_cur = vertices.top();
|
|
||||||
vertices.pop();
|
|
||||||
// get incident_vertices
|
|
||||||
std::vector<Vertex_handle> v_neighbors;
|
|
||||||
sq_distance = sq_distance + distance(v_cur,v)* distance(v_cur,v);
|
|
||||||
counter++;
|
|
||||||
m_dt.incident_vertices(v_cur,std::back_inserter(v_neighbors));
|
|
||||||
std::vector<Vertex_handle>::iterator it;
|
|
||||||
for(it = v_neighbors.begin();
|
|
||||||
it != v_neighbors.end();
|
|
||||||
it++)
|
|
||||||
{
|
|
||||||
Vertex_handle nv = *it;
|
|
||||||
int tag = nv->tag();
|
|
||||||
int index = v_cur->index();
|
|
||||||
if (tag != index)
|
|
||||||
{
|
|
||||||
vertices.push(nv);
|
|
||||||
nv->tag() = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
v->average_spacing() = std::sqrt(sq_distance/counter);
|
v->average_spacing() = std::sqrt(sq_distance/counter);
|
||||||
|
|
||||||
//}
|
|
||||||
/*for(v = m_dt.finite_vertices_begin();
|
|
||||||
v != m_dt.finite_vertices_end();
|
|
||||||
v++)
|
|
||||||
v->tag() = -1;*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -527,9 +484,7 @@ public:
|
||||||
// Compute extrapolated normals and store them in extrapolated_normals[]
|
// Compute extrapolated normals and store them in extrapolated_normals[]
|
||||||
std::map<Vertex_handle,Normal> extrapolated_normals; // vector + orientation
|
std::map<Vertex_handle,Normal> extrapolated_normals; // vector + orientation
|
||||||
Finite_vertices_iterator v;
|
Finite_vertices_iterator v;
|
||||||
for(v = m_dt.finite_vertices_begin();
|
for(v = m_dt.finite_vertices_begin(); v != m_dt.finite_vertices_end(); v++)
|
||||||
v != m_dt.finite_vertices_end();
|
|
||||||
v++)
|
|
||||||
{
|
{
|
||||||
if(v->normal() != CGAL::NULL_VECTOR)
|
if(v->normal() != CGAL::NULL_VECTOR)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -554,9 +509,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// set normals
|
// set normals
|
||||||
for(v = m_dt.finite_vertices_begin();
|
for(v = m_dt.finite_vertices_begin(); v != m_dt.finite_vertices_end(); v++)
|
||||||
v != m_dt.finite_vertices_end();
|
|
||||||
v++)
|
|
||||||
{
|
{
|
||||||
if(v->normal() != CGAL::NULL_VECTOR)
|
if(v->normal() != CGAL::NULL_VECTOR)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -573,15 +526,13 @@ public:
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extrapolate the normals field.
|
||||||
/// Extrapolate the normals field
|
/// Return the number of normals computed.
|
||||||
int extrapolate_normals_using_gaussian_kernel()
|
int extrapolate_normals_using_gaussian_kernel()
|
||||||
{
|
{
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
Finite_vertices_iterator v;
|
Finite_vertices_iterator v;
|
||||||
for(v = m_dt.finite_vertices_begin();
|
for(v = m_dt.finite_vertices_begin(); v != m_dt.finite_vertices_end(); v++)
|
||||||
v != m_dt.finite_vertices_end();
|
|
||||||
v++)
|
|
||||||
{
|
{
|
||||||
if(v->type() == Triangulation::INPUT)
|
if(v->type() == Triangulation::INPUT)
|
||||||
{
|
{
|
||||||
|
|
@ -618,12 +569,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(v = m_dt.finite_vertices_begin();
|
for(v = m_dt.finite_vertices_begin(); v != m_dt.finite_vertices_end(); v++)
|
||||||
v != m_dt.finite_vertices_end();
|
|
||||||
v++)
|
|
||||||
{
|
{
|
||||||
if(v->type() != Triangulation::INPUT )
|
if(v->type() != Triangulation::INPUT )
|
||||||
{
|
{
|
||||||
|
|
@ -633,9 +581,9 @@ public:
|
||||||
v->normal() = v->normal() / sq_norm;
|
v->normal() = v->normal() / sq_norm;
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
//v->type() = Triangulation::INPUT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ struct propagate_normal
|
||||||
// Is orientation robust?
|
// Is orientation robust?
|
||||||
//normal2 = Normal(vec2, true /* oriented */);
|
//normal2 = Normal(vec2, true /* oriented */);
|
||||||
bool oriented = normal1.is_oriented() &&
|
bool oriented = normal1.is_oriented() &&
|
||||||
(std::abs(dot) > 1.0/std::sqrt(2.0)); // oriented iff angle < 45<EFBFBD>
|
(std::abs(dot) > 1.0/std::sqrt(2.0)); // oriented iff angle < 45 degrees
|
||||||
normal2 = Normal(vec2, oriented);
|
normal2 = Normal(vec2, oriented);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
// Copyright (c) 2007-08 INRIA Sophia-Antipolis (France).
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
||||||
|
// the terms of the Q Public License version 1.0.
|
||||||
|
// See the file LICENSE.QPL distributed with CGAL.
|
||||||
|
//
|
||||||
|
// 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) : Laurent Saboret
|
||||||
|
|
||||||
|
#ifndef CGAL_RADIAL_NORMALS_ORIENTATION_3_H
|
||||||
|
#define CGAL_RADIAL_NORMALS_ORIENTATION_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Orientable_normal_3.h>
|
||||||
|
#include <CGAL/Memory_sizer.h>
|
||||||
|
#include <CGAL/surface_reconstruction_assertions.h>
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CGAL_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
/// Radial orientation of the normals of a point set.
|
||||||
|
/// Normals are oriented towards exterior of the point set.
|
||||||
|
/// This very fast method is intended to convex objects.
|
||||||
|
///
|
||||||
|
/// Preconditions:
|
||||||
|
/// - VertexIterator is a model of ForwardIterator.
|
||||||
|
/// - VertexIndexMap is a model of boost::readable_property_map.
|
||||||
|
/// - VertexPointMap is a model of boost::readable_property_map.
|
||||||
|
/// - VertexNormalMap is a model of boost::lvalue_property_map.
|
||||||
|
/// - Normals must be unit vectors.
|
||||||
|
|
||||||
|
template<class VertexIterator, class VertexPointMap, class VertexIndexMap, class VertexNormalMap>
|
||||||
|
void
|
||||||
|
radial_normals_orientation_3(VertexIterator first, ///< first input vertex
|
||||||
|
VertexIterator beyond, ///< past-the-end input vertex
|
||||||
|
VertexIndexMap vertex_index_map, ///< property map VertexIterator -> index
|
||||||
|
VertexPointMap vertex_point_map, ///< property map VertexIterator -> Point_3
|
||||||
|
VertexNormalMap vertex_normal_map) ///< property map VertexIterator -> Normal (in and out)
|
||||||
|
{
|
||||||
|
CGAL_TRACE("Call radial_normals_orientation_3()\n");
|
||||||
|
|
||||||
|
// Input mesh's types
|
||||||
|
typedef typename boost::property_traits<VertexPointMap>::value_type Point;
|
||||||
|
typedef typename boost::property_traits<VertexNormalMap>::value_type Normal;
|
||||||
|
typedef typename Normal::Vector Vector;
|
||||||
|
typedef typename Normal::Geom_traits Geom_traits; // Kernel
|
||||||
|
typedef typename Geom_traits::FT FT;
|
||||||
|
|
||||||
|
// Precondition: at least one element in the container.
|
||||||
|
CGAL_surface_reconstruction_precondition(first != beyond);
|
||||||
|
|
||||||
|
// Find points barycenter.
|
||||||
|
// Note: We should use CGAL::centroid() from PCA component.
|
||||||
|
// Unfortunately, it is not compatible with property maps.
|
||||||
|
Vector sum = CGAL::NULL_VECTOR;
|
||||||
|
int nb_points = 0;
|
||||||
|
for (VertexIterator it = first; it != beyond; it++)
|
||||||
|
{
|
||||||
|
Point point = get(vertex_point_map, it);
|
||||||
|
sum = sum + (point - CGAL::ORIGIN);
|
||||||
|
nb_points++;
|
||||||
|
}
|
||||||
|
Point barycenter = CGAL::ORIGIN + sum / (FT)nb_points;
|
||||||
|
|
||||||
|
// Radial orientation of the normals of a point set.
|
||||||
|
// Normals are oriented towards exterior of the point set.
|
||||||
|
for (VertexIterator it = first; it != beyond; it++)
|
||||||
|
{
|
||||||
|
Point point = get(vertex_point_map, it);
|
||||||
|
|
||||||
|
// Radial vector towards exterior of the point set
|
||||||
|
Vector vec1 = point - barycenter;
|
||||||
|
|
||||||
|
// Point's normal
|
||||||
|
Normal& normal2 = vertex_normal_map[it];
|
||||||
|
Vector vec2 = normal2;
|
||||||
|
|
||||||
|
double dot = vec1 * vec2;
|
||||||
|
|
||||||
|
// -> ->
|
||||||
|
// Orient vec2 parallel to vec1
|
||||||
|
if (dot < 0)
|
||||||
|
vec2 = -vec2;
|
||||||
|
|
||||||
|
// Is orientation robust?
|
||||||
|
//normal2 = Normal(vec2, true /* oriented */);
|
||||||
|
bool oriented = (std::abs(dot) > std::cos(80.*M_PI/180.)); // oriented iff angle < 80 degrees
|
||||||
|
normal2 = Normal(vec2, oriented);
|
||||||
|
}
|
||||||
|
|
||||||
|
long memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20);
|
||||||
|
CGAL_TRACE("End of radial_normals_orientation_3()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CGAL_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // CGAL_RADIAL_NORMALS_ORIENTATION_3_H
|
||||||
|
|
||||||
|
|
@ -264,10 +264,10 @@ int main(int argc, char * argv[])
|
||||||
<< " angle="<<sm_angle << " degrees,\n"
|
<< " angle="<<sm_angle << " degrees,\n"
|
||||||
<< " radius="<<sm_radius<<" * p.s.r.,\n"
|
<< " radius="<<sm_radius<<" * p.s.r.,\n"
|
||||||
<< " distance="<<sm_distance<<" * p.s.r.,\n"
|
<< " distance="<<sm_distance<<" * p.s.r.,\n"
|
||||||
<< " Manifold_tag)\n";
|
<< " Manifold_with_boundary_tag)\n";
|
||||||
|
|
||||||
// meshing surface
|
// meshing surface
|
||||||
CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Manifold_tag());
|
CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Manifold_with_boundary_tag());
|
||||||
|
|
||||||
// Print status
|
// Print status
|
||||||
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
||||||
|
|
|
||||||
|
|
@ -283,10 +283,10 @@ int main(int argc, char * argv[])
|
||||||
<< " angle="<<sm_angle << " degrees,\n"
|
<< " angle="<<sm_angle << " degrees,\n"
|
||||||
<< " radius="<<sm_radius<<" * p.s.r.,\n"
|
<< " radius="<<sm_radius<<" * p.s.r.,\n"
|
||||||
<< " distance="<<sm_distance<<" * p.s.r.,\n"
|
<< " distance="<<sm_distance<<" * p.s.r.,\n"
|
||||||
<< " Manifold_tag)\n";
|
<< " Manifold_with_boundary_tag)\n";
|
||||||
|
|
||||||
// meshing surface
|
// meshing surface
|
||||||
CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Manifold_tag());
|
CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Manifold_with_boundary_tag());
|
||||||
|
|
||||||
// Print status
|
// Print status
|
||||||
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue