RE: apply clang format
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
# FreeCAD init script of the MeshPart module
|
||||
# (c) 2001 Juergen Riegel
|
||||
|
||||
#***************************************************************************
|
||||
#* Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
|
||||
#* *
|
||||
#* This file is part of the FreeCAD CAx development system. *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* FreeCAD is distributed in the hope that it will be useful, *
|
||||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
#* GNU Lesser General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with FreeCAD; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************/
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * FreeCAD is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with FreeCAD; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
@@ -5,31 +5,31 @@
|
||||
# This is the second one of three init scripts, the third one
|
||||
# runs when the gui is up
|
||||
|
||||
#***************************************************************************
|
||||
#* Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
|
||||
#* *
|
||||
#* This file is part of the FreeCAD CAx development system. *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* FreeCAD is distributed in the hope that it will be useful, *
|
||||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
#* GNU Lesser General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with FreeCAD; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************/
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * FreeCAD is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with FreeCAD; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
|
||||
class MeshPartWorkbench ( Workbench ):
|
||||
class MeshPartWorkbench(Workbench):
|
||||
"MeshPart workbench object"
|
||||
Icon = """
|
||||
/* XPM */
|
||||
@@ -58,14 +58,13 @@ class MeshPartWorkbench ( Workbench ):
|
||||
MenuText = "MeshPart"
|
||||
ToolTip = "MeshPart workbench"
|
||||
|
||||
|
||||
def Initialize(self):
|
||||
# load the module
|
||||
import MeshPartGui
|
||||
import MeshPart
|
||||
|
||||
|
||||
def GetClassName(self):
|
||||
return "MeshPartGui::Workbench"
|
||||
|
||||
|
||||
# Gui.addWorkbench(MeshPartWorkbench())
|
||||
|
||||
@@ -29,19 +29,19 @@
|
||||
// MeshPart
|
||||
#ifndef MeshPartExport
|
||||
#ifdef MeshPart_EXPORTS
|
||||
# define MeshPartExport FREECAD_DECL_EXPORT
|
||||
#define MeshPartExport FREECAD_DECL_EXPORT
|
||||
#else
|
||||
# define MeshPartExport FREECAD_DECL_IMPORT
|
||||
#define MeshPartExport FREECAD_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// MeshPartGui
|
||||
#ifndef MeshPartGuiExport
|
||||
#ifdef MeshPartGui_EXPORTS
|
||||
# define MeshPartGuiExport FREECAD_DECL_EXPORT
|
||||
#define MeshPartGuiExport FREECAD_DECL_EXPORT
|
||||
#else
|
||||
# define MeshPartGuiExport FREECAD_DECL_IMPORT
|
||||
#define MeshPartGuiExport FREECAD_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif //MESHPART_GLOBAL_H
|
||||
#endif// MESHPART_GLOBAL_H
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <Geom_BSplineSurface.hxx>
|
||||
# include <TColgp_Array1OfPnt.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
@@ -31,13 +31,13 @@
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/PyWrapParseTupleAndKeywords.h>
|
||||
#include <Mod/Part/App/BSplineSurfacePy.h>
|
||||
#include <Mod/Mesh/App/MeshPy.h>
|
||||
#include <Mod/Part/App/BSplineSurfacePy.h>
|
||||
#include <Mod/Points/App/PointsPy.h>
|
||||
#if defined(HAVE_PCL_FILTERS)
|
||||
# include <pcl/filters/passthrough.h>
|
||||
# include <pcl/filters/voxel_grid.h>
|
||||
# include <pcl/point_types.h>
|
||||
#include <pcl/filters/passthrough.h>
|
||||
#include <pcl/filters/voxel_grid.h>
|
||||
#include <pcl/point_types.h>
|
||||
#endif
|
||||
|
||||
#include "ApproxSurface.h"
|
||||
@@ -47,7 +47,7 @@
|
||||
#include "Segmentation.h"
|
||||
#include "SurfaceTriangulation.h"
|
||||
|
||||
|
||||
// clang-format off
|
||||
/*
|
||||
Dependency of pcl components:
|
||||
common: none
|
||||
@@ -855,3 +855,4 @@ PyMOD_INIT_FUNC(ReverseEngineering)
|
||||
Base::Console().Log("Loading ReverseEngineering module... done\n");
|
||||
PyMOD_Return(mod);
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,30 +23,33 @@
|
||||
#ifndef REEN_APPROXSURFACE_H
|
||||
#define REEN_APPROXSURFACE_H
|
||||
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array2OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColgp_Array2OfPnt.hxx>
|
||||
#include <math_Matrix.hxx>
|
||||
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Mod/ReverseEngineering/ReverseEngineeringGlobal.h>
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class SequencerLauncher;
|
||||
}
|
||||
|
||||
// TODO: Replace OCC stuff with ublas & co
|
||||
|
||||
namespace Reen {
|
||||
namespace Reen
|
||||
{
|
||||
|
||||
class ReenExport SplineBasisfunction
|
||||
{
|
||||
public:
|
||||
enum ValueT {
|
||||
enum ValueT
|
||||
{
|
||||
Zero = 0,
|
||||
Full,
|
||||
Other
|
||||
@@ -62,7 +65,7 @@ public:
|
||||
* @param vKnots Knot vector
|
||||
* @param iOrder Order (degree + 1) of the basic polynomial
|
||||
*/
|
||||
explicit SplineBasisfunction(TColStd_Array1OfReal& vKnots, int iOrder=1);
|
||||
explicit SplineBasisfunction(TColStd_Array1OfReal& vKnots, int iOrder = 1);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -73,7 +76,10 @@ public:
|
||||
* and the sum of the values in @a vMults has to be identical to @a iSize.
|
||||
* @param iOrder Order (degree + 1) of the basic polynomial
|
||||
*/
|
||||
SplineBasisfunction(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iSize, int iOrder=1);
|
||||
SplineBasisfunction(TColStd_Array1OfReal& vKnots,
|
||||
TColStd_Array1OfInteger& vMults,
|
||||
int iSize,
|
||||
int iOrder = 1);
|
||||
|
||||
virtual ~SplineBasisfunction();
|
||||
|
||||
@@ -86,7 +92,7 @@ public:
|
||||
* @param fParam Parameter value
|
||||
* @return ValueT
|
||||
*/
|
||||
virtual ValueT LocalSupport(int iIndex, double fParam)=0;
|
||||
virtual ValueT LocalSupport(int iIndex, double fParam) = 0;
|
||||
/**
|
||||
* Calculates the function value Nik(t) at the point fParam
|
||||
* (from: Piegl/Tiller 96 The NURBS-Book)
|
||||
@@ -95,7 +101,7 @@ public:
|
||||
* @param fParam Parameter value
|
||||
* @return Function value Nik(t)
|
||||
*/
|
||||
virtual double BasisFunction(int iIndex, double fParam)=0;
|
||||
virtual double BasisFunction(int iIndex, double fParam) = 0;
|
||||
/**
|
||||
* Calculates the function values of the first iMaxDer derivatives on the
|
||||
* fParam position (from: Piegl/Tiller 96 The NURBS-Book)
|
||||
@@ -107,28 +113,31 @@ public:
|
||||
*
|
||||
* The list must be sufficiently long for iMaxDer+1 elements.
|
||||
*/
|
||||
virtual void DerivativesOfBasisFunction(int iIndex, int iMaxDer, double fParam,
|
||||
TColStd_Array1OfReal& Derivat)=0;
|
||||
virtual void DerivativesOfBasisFunction(int iIndex,
|
||||
int iMaxDer,
|
||||
double fParam,
|
||||
TColStd_Array1OfReal& Derivat) = 0;
|
||||
|
||||
/**
|
||||
* Calculates the kth derivative at the point fParam
|
||||
*/
|
||||
virtual double DerivativeOfBasisFunction(int iIndex, int k, double fParam)=0;
|
||||
virtual double DerivativeOfBasisFunction(int iIndex, int k, double fParam) = 0;
|
||||
|
||||
/**
|
||||
* Sets the knot vector and the order. The size of the knot vector has to be exactly as
|
||||
* large as defined in the constructor.
|
||||
*/
|
||||
virtual void SetKnots(TColStd_Array1OfReal& vKnots, int iOrder=1);
|
||||
virtual void SetKnots(TColStd_Array1OfReal& vKnots, int iOrder = 1);
|
||||
|
||||
/**
|
||||
* Sets the knot vector and the order. The knot vector in the form of (Value, Multiplicity)
|
||||
* is passed on. Internally, this is converted into a knot vector in the form of (value, 1).
|
||||
* The size of this new vector has to be exactly as big as specified in the constructor.
|
||||
*/
|
||||
virtual void SetKnots(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iOrder=1);
|
||||
virtual void
|
||||
SetKnots(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iOrder = 1);
|
||||
|
||||
protected: //Member
|
||||
protected:// Member
|
||||
// Knot vector
|
||||
TColStd_Array1OfReal _vKnotVector;
|
||||
|
||||
@@ -136,10 +145,9 @@ protected: //Member
|
||||
int _iOrder;
|
||||
};
|
||||
|
||||
class ReenExport BSplineBasis : public SplineBasisfunction
|
||||
class ReenExport BSplineBasis: public SplineBasisfunction
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param iSize Length of the knot vector
|
||||
@@ -151,7 +159,7 @@ public:
|
||||
* @param vKnots Knot vector
|
||||
* @param iOrder Order (degree + 1) of the basic polynomial
|
||||
*/
|
||||
explicit BSplineBasis(TColStd_Array1OfReal& vKnots, int iOrder=1);
|
||||
explicit BSplineBasis(TColStd_Array1OfReal& vKnots, int iOrder = 1);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -162,7 +170,10 @@ public:
|
||||
* sum of the values in @a vMults has to be identical to @a iSize.
|
||||
* @param iOrder Order (degree + 1) of the basic polynomial
|
||||
*/
|
||||
BSplineBasis(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iSize, int iOrder=1);
|
||||
BSplineBasis(TColStd_Array1OfReal& vKnots,
|
||||
TColStd_Array1OfInteger& vMults,
|
||||
int iSize,
|
||||
int iOrder = 1);
|
||||
|
||||
/**
|
||||
* Specifies the knot index for the parameter value (from: Piegl/Tiller 96 The NURBS-Book)
|
||||
@@ -173,7 +184,7 @@ public:
|
||||
|
||||
/**
|
||||
* Calculates the function values of the basic functions that do not vanish at fParam.
|
||||
* It must be ensured that the list for d (= degree of the B-spline)
|
||||
* It must be ensured that the list for d (= degree of the B-spline)
|
||||
* elements (0, ..., d-1) is sufficient (from: Piegl/Tiller 96 The NURBS-Book)
|
||||
* @param fParam Parameter
|
||||
* @param vFuncVals List of function values
|
||||
@@ -211,8 +222,10 @@ public:
|
||||
* The list must be sufficiently long for iMaxDer+1 elements.
|
||||
* @return List of function values
|
||||
*/
|
||||
void DerivativesOfBasisFunction(int iIndex, int iMaxDer, double fParam,
|
||||
TColStd_Array1OfReal& Derivat) override;
|
||||
void DerivativesOfBasisFunction(int iIndex,
|
||||
int iMaxDer,
|
||||
double fParam,
|
||||
TColStd_Array1OfReal& Derivat) override;
|
||||
|
||||
/**
|
||||
* Calculates the kth derivative at the point fParam
|
||||
@@ -229,14 +242,14 @@ public:
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~ BSplineBasis() override;
|
||||
~BSplineBasis() override;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Calculates the roots of the Legendre-Polynomials and the corresponding weights
|
||||
*/
|
||||
virtual void GenerateRootsAndWeights(TColStd_Array1OfReal& vAbscissas, TColStd_Array1OfReal& vWeights);
|
||||
virtual void GenerateRootsAndWeights(TColStd_Array1OfReal& vAbscissas,
|
||||
TColStd_Array1OfReal& vWeights);
|
||||
|
||||
/**
|
||||
* Calculates the limits of integration (Indexes of the knots)
|
||||
@@ -255,10 +268,11 @@ class ReenExport ParameterCorrection
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
explicit ParameterCorrection(unsigned usUOrder=4, //Order in u-direction (order = degree + 1)
|
||||
unsigned usVOrder=4, //Order in v-direction
|
||||
unsigned usUCtrlpoints=6, //Qty. of the control points in the u-direction
|
||||
unsigned usVCtrlpoints=6); //Qty. of the control points in the v-direction
|
||||
explicit ParameterCorrection(
|
||||
unsigned usUOrder = 4, // Order in u-direction (order = degree + 1)
|
||||
unsigned usVOrder = 4, // Order in v-direction
|
||||
unsigned usUCtrlpoints = 6, // Qty. of the control points in the u-direction
|
||||
unsigned usVCtrlpoints = 6);// Qty. of the control points in the v-direction
|
||||
|
||||
virtual ~ParameterCorrection()
|
||||
{
|
||||
@@ -285,7 +299,7 @@ protected:
|
||||
* The bounding box is calculated from these points, then the u/v parameters for
|
||||
* the points are calculated.
|
||||
*/
|
||||
virtual bool DoInitialParameterCorrection(double fSizeFactor=0.0f);
|
||||
virtual bool DoInitialParameterCorrection(double fSizeFactor = 0.0f);
|
||||
|
||||
/**
|
||||
* Calculates the (u, v) values of the points
|
||||
@@ -295,31 +309,31 @@ protected:
|
||||
/**
|
||||
* Carries out a parameter correction.
|
||||
*/
|
||||
virtual void DoParameterCorrection(int iIter)=0;
|
||||
virtual void DoParameterCorrection(int iIter) = 0;
|
||||
|
||||
/**
|
||||
* Solves system of equations
|
||||
*/
|
||||
virtual bool SolveWithoutSmoothing()=0;
|
||||
virtual bool SolveWithoutSmoothing() = 0;
|
||||
|
||||
/**
|
||||
* Solve a regular system of equations
|
||||
*/
|
||||
virtual bool SolveWithSmoothing(double fWeight)=0;
|
||||
virtual bool SolveWithSmoothing(double fWeight) = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Calculates a B-spline surface from the given points
|
||||
*/
|
||||
virtual Handle(Geom_BSplineSurface) CreateSurface(const TColgp_Array1OfPnt& points,
|
||||
int iIter,
|
||||
bool bParaCor,
|
||||
double fSizeFactor=0.0f);
|
||||
int iIter,
|
||||
bool bParaCor,
|
||||
double fSizeFactor = 0.0f);
|
||||
/**
|
||||
* Setting the u/v directions
|
||||
* The third parameter specifies whether the directions should actually be used.
|
||||
*/
|
||||
virtual void SetUV(const Base::Vector3d& clU, const Base::Vector3d& clV, bool bUseDir=true);
|
||||
virtual void SetUV(const Base::Vector3d& clU, const Base::Vector3d& clV, bool bUseDir = true);
|
||||
|
||||
/**
|
||||
* Returns the u/v/w directions
|
||||
@@ -334,26 +348,26 @@ public:
|
||||
/**
|
||||
* Use smoothing-terms
|
||||
*/
|
||||
virtual void EnableSmoothing(bool bSmooth=true, double fSmoothInfl=1.0f);
|
||||
virtual void EnableSmoothing(bool bSmooth = true, double fSmoothInfl = 1.0f);
|
||||
|
||||
protected:
|
||||
bool _bGetUVDir; //! Determines whether u/v direction is given
|
||||
bool _bSmoothing; //! Use smoothing
|
||||
double _fSmoothInfluence; //! Influence of smoothing
|
||||
unsigned _usUOrder; //! Order in u-direction
|
||||
unsigned _usVOrder; //! Order in v-direction
|
||||
unsigned _usUCtrlpoints; //! Number of control points in the u-direction
|
||||
unsigned _usVCtrlpoints; //! Number of control points in the v-direction
|
||||
Base::Vector3d _clU; //! u-direction
|
||||
Base::Vector3d _clV; //! v-direction
|
||||
Base::Vector3d _clW; //! w-direction (perpendicular to u & v directions)
|
||||
TColgp_Array1OfPnt* _pvcPoints{nullptr}; //! Raw data point list
|
||||
TColgp_Array1OfPnt2d* _pvcUVParam{nullptr}; //! Parameter value for the points in the list
|
||||
TColgp_Array2OfPnt _vCtrlPntsOfSurf; //! Array of control points
|
||||
TColStd_Array1OfReal _vUKnots; //! Knot vector of the B-spline surface in the u-direction
|
||||
TColStd_Array1OfReal _vVKnots; //! Knot vector of the B-spline surface in the v-direction
|
||||
TColStd_Array1OfInteger _vUMults; //! Multiplicity of the knots in the knot vector
|
||||
TColStd_Array1OfInteger _vVMults; //! Multiplicity of the knots in the knot vector
|
||||
bool _bGetUVDir; //! Determines whether u/v direction is given
|
||||
bool _bSmoothing; //! Use smoothing
|
||||
double _fSmoothInfluence; //! Influence of smoothing
|
||||
unsigned _usUOrder; //! Order in u-direction
|
||||
unsigned _usVOrder; //! Order in v-direction
|
||||
unsigned _usUCtrlpoints; //! Number of control points in the u-direction
|
||||
unsigned _usVCtrlpoints; //! Number of control points in the v-direction
|
||||
Base::Vector3d _clU; //! u-direction
|
||||
Base::Vector3d _clV; //! v-direction
|
||||
Base::Vector3d _clW; //! w-direction (perpendicular to u & v directions)
|
||||
TColgp_Array1OfPnt* _pvcPoints {nullptr}; //! Raw data point list
|
||||
TColgp_Array1OfPnt2d* _pvcUVParam {nullptr};//! Parameter value for the points in the list
|
||||
TColgp_Array2OfPnt _vCtrlPntsOfSurf; //! Array of control points
|
||||
TColStd_Array1OfReal _vUKnots; //! Knot vector of the B-spline surface in the u-direction
|
||||
TColStd_Array1OfReal _vVKnots; //! Knot vector of the B-spline surface in the v-direction
|
||||
TColStd_Array1OfInteger _vUMults;//! Multiplicity of the knots in the knot vector
|
||||
TColStd_Array1OfInteger _vVMults;//! Multiplicity of the knots in the knot vector
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -366,14 +380,15 @@ protected:
|
||||
* can be generated.
|
||||
*/
|
||||
|
||||
class ReenExport BSplineParameterCorrection : public ParameterCorrection
|
||||
class ReenExport BSplineParameterCorrection: public ParameterCorrection
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
explicit BSplineParameterCorrection(unsigned usUOrder=4, //Order in u-direction (order = degree + 1)
|
||||
unsigned usVOrder=4, //Order in the v-direction
|
||||
unsigned usUCtrlpoints=6, //Qty. of the control points in u-direction
|
||||
unsigned usVCtrlpoints=6); //Qty. of the control points in v-direction
|
||||
explicit BSplineParameterCorrection(
|
||||
unsigned usUOrder = 4, // Order in u-direction (order = degree + 1)
|
||||
unsigned usVOrder = 4, // Order in the v-direction
|
||||
unsigned usUCtrlpoints = 6, // Qty. of the control points in u-direction
|
||||
unsigned usVCtrlpoints = 6);// Qty. of the control points in v-direction
|
||||
|
||||
~BSplineParameterCorrection() override = default;
|
||||
|
||||
@@ -443,13 +458,13 @@ public:
|
||||
/**
|
||||
* Use smoothing-terms
|
||||
*/
|
||||
void EnableSmoothing(bool bSmooth=true, double fSmoothInfl=1.0f) override;
|
||||
void EnableSmoothing(bool bSmooth = true, double fSmoothInfl = 1.0f) override;
|
||||
|
||||
/**
|
||||
* Use smoothing-terms
|
||||
*/
|
||||
virtual void EnableSmoothing(bool bSmooth, double fSmoothInfl,
|
||||
double fFirst, double fSec, double fThird);
|
||||
virtual void
|
||||
EnableSmoothing(bool bSmooth, double fSmoothInfl, double fFirst, double fSec, double fThird);
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -476,14 +491,14 @@ protected:
|
||||
virtual void CalcThirdSmoothMatrix(Base::SequencerLauncher&);
|
||||
|
||||
protected:
|
||||
BSplineBasis _clUSpline; //! B-spline basic function in the u-direction
|
||||
BSplineBasis _clVSpline; //! B-spline basic function in the v-direction
|
||||
math_Matrix _clSmoothMatrix; //! Matrix of smoothing functionals
|
||||
math_Matrix _clFirstMatrix; //! Matrix of the 1st smoothing functionals
|
||||
math_Matrix _clSecondMatrix; //! Matrix of the 2nd smoothing functionals
|
||||
math_Matrix _clThirdMatrix; //! Matrix of the 3rd smoothing functionals
|
||||
BSplineBasis _clUSpline; //! B-spline basic function in the u-direction
|
||||
BSplineBasis _clVSpline; //! B-spline basic function in the v-direction
|
||||
math_Matrix _clSmoothMatrix;//! Matrix of smoothing functionals
|
||||
math_Matrix _clFirstMatrix; //! Matrix of the 1st smoothing functionals
|
||||
math_Matrix _clSecondMatrix;//! Matrix of the 2nd smoothing functionals
|
||||
math_Matrix _clThirdMatrix; //! Matrix of the 3rd smoothing functionals
|
||||
};
|
||||
|
||||
} // namespace Reen
|
||||
}// namespace Reen
|
||||
|
||||
#endif // REEN_APPROXSURFACE_H
|
||||
#endif// REEN_APPROXSURFACE_H
|
||||
|
||||
@@ -23,13 +23,13 @@
|
||||
#include "PreCompiled.h"
|
||||
#if defined(HAVE_PCL_OPENNURBS)
|
||||
#ifndef _PreComp_
|
||||
# include <map>
|
||||
#include <map>
|
||||
|
||||
# include <Geom_BSplineSurface.hxx>
|
||||
# include <TColgp_Array2OfPnt.hxx>
|
||||
# include <TColStd_Array1OfInteger.hxx>
|
||||
# include <TColStd_Array1OfReal.hxx>
|
||||
# include <TColStd_Array2OfReal.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array2OfReal.hxx>
|
||||
#include <TColgp_Array2OfPnt.hxx>
|
||||
#endif
|
||||
|
||||
#include <Mod/Points/App/PointsPy.h>
|
||||
@@ -37,28 +37,27 @@
|
||||
#include "BSplineFitting.h"
|
||||
|
||||
#include <pcl/pcl_config.h>
|
||||
#if PCL_VERSION_COMPARE(>=,1,7,0)
|
||||
# include <pcl/point_cloud.h>
|
||||
# include <pcl/point_types.h>
|
||||
# include <pcl/io/pcd_io.h>
|
||||
# include <pcl/surface/on_nurbs/fitting_surface_tdm.h>
|
||||
# include <pcl/surface/on_nurbs/fitting_curve_2d_asdm.h>
|
||||
#if PCL_VERSION_COMPARE(>=, 1, 7, 0)
|
||||
#include <pcl/io/pcd_io.h>
|
||||
#include <pcl/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
#include <pcl/surface/on_nurbs/fitting_curve_2d_asdm.h>
|
||||
#include <pcl/surface/on_nurbs/fitting_surface_tdm.h>
|
||||
#endif
|
||||
|
||||
using namespace Reen;
|
||||
|
||||
|
||||
BSplineFitting::BSplineFitting(const std::vector<Base::Vector3f>& pts)
|
||||
: myPoints(pts)
|
||||
, myIterations(10)
|
||||
, myOrder(3)
|
||||
, myRefinement(4)
|
||||
, myInteriorSmoothness(0.2)
|
||||
, myInteriorWeight(1.0)
|
||||
, myBoundarySmoothness(0.2)
|
||||
, myBoundaryWeight(0.0)
|
||||
{
|
||||
}
|
||||
: myPoints(pts)
|
||||
, myIterations(10)
|
||||
, myOrder(3)
|
||||
, myRefinement(4)
|
||||
, myInteriorSmoothness(0.2)
|
||||
, myInteriorWeight(1.0)
|
||||
, myBoundarySmoothness(0.2)
|
||||
, myBoundaryWeight(0.0)
|
||||
{}
|
||||
|
||||
void BSplineFitting::setIterations(unsigned value)
|
||||
{
|
||||
@@ -97,11 +96,13 @@ void BSplineFitting::setBoundaryWeight(double value)
|
||||
|
||||
Handle(Geom_BSplineSurface) BSplineFitting::perform()
|
||||
{
|
||||
#if PCL_VERSION_COMPARE(>=,1,7,0)
|
||||
#if PCL_VERSION_COMPARE(>=, 1, 7, 0)
|
||||
pcl::on_nurbs::NurbsDataSurface data;
|
||||
for (std::vector<Base::Vector3f>::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
if (!pcl_isnan (it->x) && !pcl_isnan (it->y) && !pcl_isnan (it->z))
|
||||
data.interior.push_back (Eigen::Vector3d (it->x, it->y, it->z));
|
||||
for (std::vector<Base::Vector3f>::const_iterator it = myPoints.begin(); it != myPoints.end();
|
||||
++it) {
|
||||
if (!pcl_isnan(it->x) && !pcl_isnan(it->y) && !pcl_isnan(it->z)) {
|
||||
data.interior.push_back(Eigen::Vector3d(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,8 +116,8 @@ Handle(Geom_BSplineSurface) BSplineFitting::perform()
|
||||
params.boundary_weight = myBoundaryWeight;
|
||||
|
||||
// initialize
|
||||
ON_NurbsSurface nurbs = pcl::on_nurbs::FittingSurface::initNurbsPCABoundingBox (myOrder, &data);
|
||||
pcl::on_nurbs::FittingSurface fit (&data, nurbs);
|
||||
ON_NurbsSurface nurbs = pcl::on_nurbs::FittingSurface::initNurbsPCABoundingBox(myOrder, &data);
|
||||
pcl::on_nurbs::FittingSurface fit(&data, nurbs);
|
||||
// fit.setQuiet (false); // enable/disable debug output
|
||||
|
||||
// surface refinement
|
||||
@@ -179,61 +180,74 @@ Handle(Geom_BSplineSurface) BSplineFitting::perform()
|
||||
TColgp_Array2OfPnt poles(1, numUPoles, 1, numVPoles);
|
||||
TColStd_Array2OfReal weights(1, numUPoles, 1, numVPoles);
|
||||
|
||||
for (int i=0; i<numUPoles; i++) {
|
||||
for (int j=0; j<numVPoles; j++) {
|
||||
for (int i = 0; i < numUPoles; i++) {
|
||||
for (int j = 0; j < numVPoles; j++) {
|
||||
ON_3dPoint cv;
|
||||
fit.m_nurbs.GetCV(i, j, cv);
|
||||
poles.SetValue(i+1, j+1, gp_Pnt(cv.x,cv.y,cv.z));
|
||||
poles.SetValue(i + 1, j + 1, gp_Pnt(cv.x, cv.y, cv.z));
|
||||
|
||||
Standard_Real weight = fit.m_nurbs.Weight(i, j);
|
||||
weights.SetValue(i+1, j+1, weight);
|
||||
weights.SetValue(i + 1, j + 1, weight);
|
||||
}
|
||||
}
|
||||
|
||||
uKnots[fit.m_nurbs.SuperfluousKnot(0,0)] = 1;
|
||||
uKnots[fit.m_nurbs.SuperfluousKnot(0,1)] = 1;
|
||||
for (int i=0; i<numUKnots; i++) {
|
||||
uKnots[fit.m_nurbs.SuperfluousKnot(0, 0)] = 1;
|
||||
uKnots[fit.m_nurbs.SuperfluousKnot(0, 1)] = 1;
|
||||
for (int i = 0; i < numUKnots; i++) {
|
||||
Standard_Real value = fit.m_nurbs.Knot(0, i);
|
||||
std::map<Standard_Real, int>::iterator it = uKnots.find(value);
|
||||
if (it == uKnots.end())
|
||||
if (it == uKnots.end()) {
|
||||
uKnots[value] = 1;
|
||||
else
|
||||
}
|
||||
else {
|
||||
it->second++;
|
||||
}
|
||||
}
|
||||
|
||||
vKnots[fit.m_nurbs.SuperfluousKnot(1,0)] = 1;
|
||||
vKnots[fit.m_nurbs.SuperfluousKnot(1,1)] = 1;
|
||||
for (int i=0; i<numVKnots; i++) {
|
||||
vKnots[fit.m_nurbs.SuperfluousKnot(1, 0)] = 1;
|
||||
vKnots[fit.m_nurbs.SuperfluousKnot(1, 1)] = 1;
|
||||
for (int i = 0; i < numVKnots; i++) {
|
||||
Standard_Real value = fit.m_nurbs.Knot(1, i);
|
||||
std::map<Standard_Real, int>::iterator it = vKnots.find(value);
|
||||
if (it == vKnots.end())
|
||||
if (it == vKnots.end()) {
|
||||
vKnots[value] = 1;
|
||||
else
|
||||
}
|
||||
else {
|
||||
it->second++;
|
||||
}
|
||||
}
|
||||
|
||||
TColStd_Array1OfReal uKnotArray(1,uKnots.size());
|
||||
TColStd_Array1OfInteger uMultArray(1,uKnots.size());
|
||||
TColStd_Array1OfReal uKnotArray(1, uKnots.size());
|
||||
TColStd_Array1OfInteger uMultArray(1, uKnots.size());
|
||||
int index = 1;
|
||||
for (std::map<Standard_Real, int>::iterator it = uKnots.begin(); it != uKnots.end(); ++it, index++) {
|
||||
for (std::map<Standard_Real, int>::iterator it = uKnots.begin(); it != uKnots.end();
|
||||
++it, index++) {
|
||||
uKnotArray.SetValue(index, it->first);
|
||||
uMultArray.SetValue(index, it->second);
|
||||
}
|
||||
|
||||
TColStd_Array1OfReal vKnotArray(1,vKnots.size());
|
||||
TColStd_Array1OfInteger vMultArray(1,vKnots.size());
|
||||
TColStd_Array1OfReal vKnotArray(1, vKnots.size());
|
||||
TColStd_Array1OfInteger vMultArray(1, vKnots.size());
|
||||
index = 1;
|
||||
for (std::map<Standard_Real, int>::iterator it = vKnots.begin(); it != vKnots.end(); ++it, index++) {
|
||||
for (std::map<Standard_Real, int>::iterator it = vKnots.begin(); it != vKnots.end();
|
||||
++it, index++) {
|
||||
vKnotArray.SetValue(index, it->first);
|
||||
vMultArray.SetValue(index, it->second);
|
||||
}
|
||||
|
||||
Handle(Geom_BSplineSurface) spline = new Geom_BSplineSurface(poles,weights,
|
||||
uKnotArray, vKnotArray, uMultArray, vMultArray, uDegree, vDegree,
|
||||
uPeriodic, vPeriodic);
|
||||
Handle(Geom_BSplineSurface) spline = new Geom_BSplineSurface(poles,
|
||||
weights,
|
||||
uKnotArray,
|
||||
vKnotArray,
|
||||
uMultArray,
|
||||
vMultArray,
|
||||
uDegree,
|
||||
vDegree,
|
||||
uPeriodic,
|
||||
vPeriodic);
|
||||
return spline;
|
||||
#else
|
||||
return Handle(Geom_BSplineSurface)();
|
||||
#endif
|
||||
}
|
||||
#endif // HAVE_PCL_OPENNURBS
|
||||
#endif// HAVE_PCL_OPENNURBS
|
||||
|
||||
@@ -24,13 +24,14 @@
|
||||
#define REEN_BSPLINEFITTING_H
|
||||
|
||||
#if defined(HAVE_PCL_OPENNURBS)
|
||||
# include <vector>
|
||||
#include <vector>
|
||||
|
||||
# include <Base/Vector3D.h>
|
||||
# include <Geom_BSplineSurface.hxx>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
|
||||
|
||||
namespace Reen {
|
||||
namespace Reen
|
||||
{
|
||||
|
||||
class BSplineFitting
|
||||
{
|
||||
@@ -57,8 +58,8 @@ private:
|
||||
double myBoundaryWeight;
|
||||
};
|
||||
|
||||
}
|
||||
}// namespace Reen
|
||||
|
||||
#endif // HAVE_PCL_OPENNURBS
|
||||
#endif// HAVE_PCL_OPENNURBS
|
||||
|
||||
#endif // REEN_BSPLINEFITTING_H
|
||||
#endif// REEN_BSPLINEFITTING_H
|
||||
|
||||
@@ -26,16 +26,16 @@
|
||||
#include <FCConfig.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable : 4181)
|
||||
# pragma warning(disable : 4267)
|
||||
# pragma warning(disable : 4275)
|
||||
# pragma warning(disable : 4305)
|
||||
# pragma warning(disable : 4522)
|
||||
#pragma warning(disable : 4181)
|
||||
#pragma warning(disable : 4267)
|
||||
#pragma warning(disable : 4275)
|
||||
#pragma warning(disable : 4305)
|
||||
#pragma warning(disable : 4522)
|
||||
#endif
|
||||
|
||||
// pcl headers include <boost/bind.hpp> instead of <boost/bind/bind.hpp>
|
||||
#ifndef BOOST_BIND_GLOBAL_PLACEHOLDERS
|
||||
# define BOOST_BIND_GLOBAL_PLACEHOLDERS
|
||||
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
|
||||
#endif
|
||||
|
||||
#ifdef _PreComp_
|
||||
@@ -48,15 +48,15 @@
|
||||
|
||||
// OpenCasCade
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <math_Gauss.hxx>
|
||||
#include <math_Householder.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <math_Gauss.hxx>
|
||||
#include <math_Householder.hxx>
|
||||
|
||||
// Qt
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#include <QtConcurrentMap>
|
||||
|
||||
#endif // _PreComp_
|
||||
#endif// _PreComp_
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#endif
|
||||
|
||||
#include <Mod/Points/App/Points.h>
|
||||
@@ -31,69 +31,71 @@
|
||||
|
||||
|
||||
#if defined(HAVE_PCL_FILTERS)
|
||||
# include <pcl/filters/passthrough.h>
|
||||
# include <pcl/point_types.h>
|
||||
#include <pcl/filters/passthrough.h>
|
||||
#include <pcl/point_types.h>
|
||||
#endif
|
||||
#if defined(HAVE_PCL_SEGMENTATION)
|
||||
# include <pcl/search/search.h>
|
||||
# include <pcl/search/kdtree.h>
|
||||
# include <pcl/features/normal_3d.h>
|
||||
# include <pcl/segmentation/region_growing.h>
|
||||
# include <pcl/filters/extract_indices.h>
|
||||
#include <pcl/features/normal_3d.h>
|
||||
#include <pcl/filters/extract_indices.h>
|
||||
#include <pcl/search/kdtree.h>
|
||||
#include <pcl/search/search.h>
|
||||
#include <pcl/segmentation/region_growing.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Reen;
|
||||
using pcl::PointXYZ;
|
||||
using pcl::PointNormal;
|
||||
using pcl::PointCloud;
|
||||
using pcl::PointNormal;
|
||||
using pcl::PointXYZ;
|
||||
|
||||
RegionGrowing::RegionGrowing(const Points::PointKernel& pts, std::list<std::vector<int> >& clusters)
|
||||
: myPoints(pts)
|
||||
, myClusters(clusters)
|
||||
{
|
||||
}
|
||||
RegionGrowing::RegionGrowing(const Points::PointKernel& pts, std::list<std::vector<int>>& clusters)
|
||||
: myPoints(pts)
|
||||
, myClusters(clusters)
|
||||
{}
|
||||
|
||||
void RegionGrowing::perform(int ksearch)
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
cloud->reserve(myPoints.size());
|
||||
for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y)
|
||||
&& !boost::math::isnan(it->z)) {
|
||||
cloud->push_back(pcl::PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
|
||||
//normal estimation
|
||||
// normal estimation
|
||||
pcl::search::Search<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
|
||||
pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
|
||||
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimator;
|
||||
normal_estimator.setSearchMethod (tree);
|
||||
normal_estimator.setInputCloud (cloud);
|
||||
normal_estimator.setKSearch (ksearch);
|
||||
normal_estimator.compute (*normals);
|
||||
normal_estimator.setSearchMethod(tree);
|
||||
normal_estimator.setInputCloud(cloud);
|
||||
normal_estimator.setKSearch(ksearch);
|
||||
normal_estimator.compute(*normals);
|
||||
|
||||
// pass through
|
||||
pcl::IndicesPtr indices (new std::vector <int>);
|
||||
pcl::IndicesPtr indices(new std::vector<int>);
|
||||
pcl::PassThrough<pcl::PointXYZ> pass;
|
||||
pass.setInputCloud (cloud);
|
||||
pass.setFilterFieldName ("z");
|
||||
pass.setFilterLimits (0.0, 1.0);
|
||||
pass.filter (*indices);
|
||||
pass.setInputCloud(cloud);
|
||||
pass.setFilterFieldName("z");
|
||||
pass.setFilterLimits(0.0, 1.0);
|
||||
pass.filter(*indices);
|
||||
|
||||
pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;
|
||||
reg.setMinClusterSize (50);
|
||||
reg.setMaxClusterSize (1000000);
|
||||
reg.setSearchMethod (tree);
|
||||
reg.setNumberOfNeighbours (30);
|
||||
reg.setInputCloud (cloud);
|
||||
//reg.setIndices (indices);
|
||||
reg.setInputNormals (normals);
|
||||
reg.setSmoothnessThreshold (3.0 / 180.0 * M_PI);
|
||||
reg.setCurvatureThreshold (1.0);
|
||||
reg.setMinClusterSize(50);
|
||||
reg.setMaxClusterSize(1000000);
|
||||
reg.setSearchMethod(tree);
|
||||
reg.setNumberOfNeighbours(30);
|
||||
reg.setInputCloud(cloud);
|
||||
// reg.setIndices (indices);
|
||||
reg.setInputNormals(normals);
|
||||
reg.setSmoothnessThreshold(3.0 / 180.0 * M_PI);
|
||||
reg.setCurvatureThreshold(1.0);
|
||||
|
||||
std::vector <pcl::PointIndices> clusters;
|
||||
reg.extract (clusters);
|
||||
std::vector<pcl::PointIndices> clusters;
|
||||
reg.extract(clusters);
|
||||
|
||||
for (std::vector<pcl::PointIndices>::iterator it = clusters.begin (); it != clusters.end (); ++it) {
|
||||
for (std::vector<pcl::PointIndices>::iterator it = clusters.begin(); it != clusters.end();
|
||||
++it) {
|
||||
myClusters.push_back(std::vector<int>());
|
||||
myClusters.back().swap(it->indices);
|
||||
}
|
||||
@@ -101,17 +103,18 @@ void RegionGrowing::perform(int ksearch)
|
||||
|
||||
void RegionGrowing::perform(const std::vector<Base::Vector3f>& myNormals)
|
||||
{
|
||||
if (myPoints.size() != myNormals.size())
|
||||
if (myPoints.size() != myNormals.size()) {
|
||||
throw Base::RuntimeError("Number of points doesn't match with number of normals");
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
cloud->reserve(myPoints.size());
|
||||
pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
|
||||
normals->reserve(myNormals.size());
|
||||
|
||||
std::size_t num_points = myPoints.size();
|
||||
const std::vector<Base::Vector3f>& points = myPoints.getBasicPoints();
|
||||
for (std::size_t index=0; index<num_points; index++) {
|
||||
for (std::size_t index = 0; index < num_points; index++) {
|
||||
const Base::Vector3f& p = points[index];
|
||||
const Base::Vector3f& n = myNormals[index];
|
||||
if (!boost::math::isnan(p.x) && !boost::math::isnan(p.y) && !boost::math::isnan(p.z)) {
|
||||
@@ -121,35 +124,35 @@ void RegionGrowing::perform(const std::vector<Base::Vector3f>& myNormals)
|
||||
}
|
||||
|
||||
pcl::search::Search<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
|
||||
tree->setInputCloud (cloud);
|
||||
tree->setInputCloud(cloud);
|
||||
|
||||
// pass through
|
||||
pcl::IndicesPtr indices (new std::vector <int>);
|
||||
pcl::IndicesPtr indices(new std::vector<int>);
|
||||
pcl::PassThrough<pcl::PointXYZ> pass;
|
||||
pass.setInputCloud (cloud);
|
||||
pass.setFilterFieldName ("z");
|
||||
pass.setFilterLimits (0.0, 1.0);
|
||||
pass.filter (*indices);
|
||||
pass.setInputCloud(cloud);
|
||||
pass.setFilterFieldName("z");
|
||||
pass.setFilterLimits(0.0, 1.0);
|
||||
pass.filter(*indices);
|
||||
|
||||
pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;
|
||||
reg.setMinClusterSize (50);
|
||||
reg.setMaxClusterSize (1000000);
|
||||
reg.setSearchMethod (tree);
|
||||
reg.setNumberOfNeighbours (30);
|
||||
reg.setInputCloud (cloud);
|
||||
//reg.setIndices (indices);
|
||||
reg.setInputNormals (normals);
|
||||
reg.setSmoothnessThreshold (3.0 / 180.0 * M_PI);
|
||||
reg.setCurvatureThreshold (1.0);
|
||||
reg.setMinClusterSize(50);
|
||||
reg.setMaxClusterSize(1000000);
|
||||
reg.setSearchMethod(tree);
|
||||
reg.setNumberOfNeighbours(30);
|
||||
reg.setInputCloud(cloud);
|
||||
// reg.setIndices (indices);
|
||||
reg.setInputNormals(normals);
|
||||
reg.setSmoothnessThreshold(3.0 / 180.0 * M_PI);
|
||||
reg.setCurvatureThreshold(1.0);
|
||||
|
||||
std::vector <pcl::PointIndices> clusters;
|
||||
reg.extract (clusters);
|
||||
std::vector<pcl::PointIndices> clusters;
|
||||
reg.extract(clusters);
|
||||
|
||||
for (std::vector<pcl::PointIndices>::iterator it = clusters.begin (); it != clusters.end (); ++it) {
|
||||
for (std::vector<pcl::PointIndices>::iterator it = clusters.begin(); it != clusters.end();
|
||||
++it) {
|
||||
myClusters.push_back(std::vector<int>());
|
||||
myClusters.back().swap(it->indices);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_PCL_SEGMENTATION
|
||||
|
||||
#endif// HAVE_PCL_SEGMENTATION
|
||||
|
||||
@@ -29,29 +29,32 @@
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
|
||||
namespace Points {class PointKernel;}
|
||||
namespace Points
|
||||
{
|
||||
class PointKernel;
|
||||
}
|
||||
|
||||
namespace Reen {
|
||||
namespace Reen
|
||||
{
|
||||
|
||||
class RegionGrowing
|
||||
{
|
||||
public:
|
||||
RegionGrowing(const Points::PointKernel&, std::list<std::vector<int> >&);
|
||||
RegionGrowing(const Points::PointKernel&, std::list<std::vector<int>>&);
|
||||
/** \brief Set the number of k nearest neighbors to use for the normal estimation.
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch);
|
||||
/** \brief Pass the normals to the points given in the constructor.
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
void perform(const std::vector<Base::Vector3f>& normals);
|
||||
|
||||
private:
|
||||
const Points::PointKernel& myPoints;
|
||||
std::list<std::vector<int> >& myClusters;
|
||||
std::list<std::vector<int>>& myClusters;
|
||||
};
|
||||
|
||||
} // namespace Reen
|
||||
|
||||
#endif // REEN_REGIONGROWING_H
|
||||
}// namespace Reen
|
||||
|
||||
#endif// REEN_REGIONGROWING_H
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#endif
|
||||
|
||||
#include <Base/Exception.h>
|
||||
@@ -32,41 +32,44 @@
|
||||
|
||||
|
||||
#if defined(HAVE_PCL_SAMPLE_CONSENSUS)
|
||||
# include <pcl/point_types.h>
|
||||
# include <pcl/features/normal_3d.h>
|
||||
# include <pcl/sample_consensus/ransac.h>
|
||||
# include <pcl/sample_consensus/sac_model_cone.h>
|
||||
# include <pcl/sample_consensus/sac_model_cylinder.h>
|
||||
# include <pcl/sample_consensus/sac_model_plane.h>
|
||||
# include <pcl/sample_consensus/sac_model_sphere.h>
|
||||
#include <pcl/features/normal_3d.h>
|
||||
#include <pcl/point_types.h>
|
||||
#include <pcl/sample_consensus/ransac.h>
|
||||
#include <pcl/sample_consensus/sac_model_cone.h>
|
||||
#include <pcl/sample_consensus/sac_model_cylinder.h>
|
||||
#include <pcl/sample_consensus/sac_model_plane.h>
|
||||
#include <pcl/sample_consensus/sac_model_sphere.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Reen;
|
||||
using pcl::PointXYZ;
|
||||
using pcl::PointNormal;
|
||||
using pcl::PointCloud;
|
||||
using pcl::PointNormal;
|
||||
using pcl::PointXYZ;
|
||||
|
||||
SampleConsensus::SampleConsensus(SacModel sac, const Points::PointKernel& pts, const std::vector<Base::Vector3d>& nor)
|
||||
: mySac(sac)
|
||||
, myPoints(pts)
|
||||
, myNormals(nor)
|
||||
{
|
||||
}
|
||||
SampleConsensus::SampleConsensus(SacModel sac,
|
||||
const Points::PointKernel& pts,
|
||||
const std::vector<Base::Vector3d>& nor)
|
||||
: mySac(sac)
|
||||
, myPoints(pts)
|
||||
, myNormals(nor)
|
||||
{}
|
||||
|
||||
double SampleConsensus::perform(std::vector<float>& parameters, std::vector<int>& model)
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
cloud->reserve(myPoints.size());
|
||||
for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y)
|
||||
&& !boost::math::isnan(it->z)) {
|
||||
cloud->push_back(pcl::PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
|
||||
cloud->width = int (cloud->points.size ());
|
||||
cloud->width = int(cloud->points.size());
|
||||
cloud->height = 1;
|
||||
cloud->is_dense = true;
|
||||
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal> ());
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>());
|
||||
if (mySac == SACMODEL_CONE || mySac == SACMODEL_CYLINDER) {
|
||||
#if 0
|
||||
// Create search tree
|
||||
@@ -83,9 +86,13 @@ double SampleConsensus::perform(std::vector<float>& parameters, std::vector<int>
|
||||
n.compute (*normals);
|
||||
#else
|
||||
normals->reserve(myNormals.size());
|
||||
for (std::vector<Base::Vector3d>::const_iterator it = myNormals.begin(); it != myNormals.end(); ++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
|
||||
for (std::vector<Base::Vector3d>::const_iterator it = myNormals.begin();
|
||||
it != myNormals.end();
|
||||
++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y)
|
||||
&& !boost::math::isnan(it->z)) {
|
||||
normals->push_back(pcl::Normal(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -93,48 +100,44 @@ double SampleConsensus::perform(std::vector<float>& parameters, std::vector<int>
|
||||
// created RandomSampleConsensus object and compute the appropriated model
|
||||
pcl::SampleConsensusModel<pcl::PointXYZ>::Ptr model_p;
|
||||
switch (mySac) {
|
||||
case SACMODEL_PLANE:
|
||||
{
|
||||
model_p.reset(new pcl::SampleConsensusModelPlane<pcl::PointXYZ> (cloud));
|
||||
break;
|
||||
}
|
||||
case SACMODEL_SPHERE:
|
||||
{
|
||||
model_p.reset(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (cloud));
|
||||
break;
|
||||
}
|
||||
case SACMODEL_CONE:
|
||||
{
|
||||
pcl::SampleConsensusModelCone<pcl::PointXYZ, pcl::Normal>::Ptr model_c
|
||||
(new pcl::SampleConsensusModelCone<pcl::PointXYZ, pcl::Normal> (cloud));
|
||||
model_c->setInputNormals(normals);
|
||||
model_p = model_c;
|
||||
break;
|
||||
}
|
||||
case SACMODEL_CYLINDER:
|
||||
{
|
||||
pcl::SampleConsensusModelCylinder<pcl::PointXYZ, pcl::Normal>::Ptr model_c
|
||||
(new pcl::SampleConsensusModelCylinder<pcl::PointXYZ, pcl::Normal> (cloud));
|
||||
model_c->setInputNormals(normals);
|
||||
model_p = model_c;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw Base::RuntimeError("Unsupported SAC model");
|
||||
case SACMODEL_PLANE: {
|
||||
model_p.reset(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(cloud));
|
||||
break;
|
||||
}
|
||||
case SACMODEL_SPHERE: {
|
||||
model_p.reset(new pcl::SampleConsensusModelSphere<pcl::PointXYZ>(cloud));
|
||||
break;
|
||||
}
|
||||
case SACMODEL_CONE: {
|
||||
pcl::SampleConsensusModelCone<pcl::PointXYZ, pcl::Normal>::Ptr model_c(
|
||||
new pcl::SampleConsensusModelCone<pcl::PointXYZ, pcl::Normal>(cloud));
|
||||
model_c->setInputNormals(normals);
|
||||
model_p = model_c;
|
||||
break;
|
||||
}
|
||||
case SACMODEL_CYLINDER: {
|
||||
pcl::SampleConsensusModelCylinder<pcl::PointXYZ, pcl::Normal>::Ptr model_c(
|
||||
new pcl::SampleConsensusModelCylinder<pcl::PointXYZ, pcl::Normal>(cloud));
|
||||
model_c->setInputNormals(normals);
|
||||
model_p = model_c;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw Base::RuntimeError("Unsupported SAC model");
|
||||
}
|
||||
|
||||
pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_p);
|
||||
ransac.setDistanceThreshold (.01);
|
||||
pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_p);
|
||||
ransac.setDistanceThreshold(.01);
|
||||
ransac.computeModel();
|
||||
ransac.getInliers(model);
|
||||
//ransac.getModel (model);
|
||||
// ransac.getModel (model);
|
||||
Eigen::VectorXf model_p_coefficients;
|
||||
ransac.getModelCoefficients (model_p_coefficients);
|
||||
for (int i=0; i<model_p_coefficients.size(); i++)
|
||||
ransac.getModelCoefficients(model_p_coefficients);
|
||||
for (int i = 0; i < model_p_coefficients.size(); i++) {
|
||||
parameters.push_back(model_p_coefficients[i]);
|
||||
}
|
||||
|
||||
return ransac.getProbability();
|
||||
}
|
||||
|
||||
#endif // HAVE_PCL_SAMPLE_CONSENSUS
|
||||
|
||||
#endif// HAVE_PCL_SAMPLE_CONSENSUS
|
||||
|
||||
@@ -28,23 +28,27 @@
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
|
||||
namespace Points {class PointKernel;}
|
||||
namespace Points
|
||||
{
|
||||
class PointKernel;
|
||||
}
|
||||
|
||||
namespace Reen {
|
||||
namespace Reen
|
||||
{
|
||||
|
||||
class SampleConsensus
|
||||
{
|
||||
public:
|
||||
enum SacModel
|
||||
{
|
||||
SACMODEL_PLANE,
|
||||
SACMODEL_LINE,
|
||||
SACMODEL_CIRCLE2D,
|
||||
SACMODEL_CIRCLE3D,
|
||||
SACMODEL_SPHERE,
|
||||
SACMODEL_CYLINDER,
|
||||
SACMODEL_CONE,
|
||||
SACMODEL_TORUS,
|
||||
SACMODEL_PLANE,
|
||||
SACMODEL_LINE,
|
||||
SACMODEL_CIRCLE2D,
|
||||
SACMODEL_CIRCLE3D,
|
||||
SACMODEL_SPHERE,
|
||||
SACMODEL_CYLINDER,
|
||||
SACMODEL_CONE,
|
||||
SACMODEL_TORUS,
|
||||
};
|
||||
SampleConsensus(SacModel sac, const Points::PointKernel&, const std::vector<Base::Vector3d>&);
|
||||
double perform(std::vector<float>& parameters, std::vector<int>& model);
|
||||
@@ -55,7 +59,6 @@ private:
|
||||
const std::vector<Base::Vector3d>& myNormals;
|
||||
};
|
||||
|
||||
} // namespace Reen
|
||||
|
||||
#endif // REEN_SAMPLECONSENSUS_H
|
||||
}// namespace Reen
|
||||
|
||||
#endif// REEN_SAMPLECONSENSUS_H
|
||||
|
||||
@@ -28,38 +28,37 @@
|
||||
|
||||
|
||||
#if defined(HAVE_PCL_FILTERS)
|
||||
# include <pcl/filters/extract_indices.h>
|
||||
# include <pcl/filters/passthrough.h>
|
||||
# include <pcl/features/normal_3d.h>
|
||||
#include <pcl/features/normal_3d.h>
|
||||
#include <pcl/filters/extract_indices.h>
|
||||
#include <pcl/filters/passthrough.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PCL_SAMPLE_CONSENSUS)
|
||||
# include <pcl/sample_consensus/method_types.h>
|
||||
# include <pcl/sample_consensus/model_types.h>
|
||||
#include <pcl/sample_consensus/method_types.h>
|
||||
#include <pcl/sample_consensus/model_types.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PCL_SEGMENTATION)
|
||||
# include <pcl/io/pcd_io.h>
|
||||
# include <pcl/ModelCoefficients.h>
|
||||
# include <pcl/point_types.h>
|
||||
# include <pcl/segmentation/sac_segmentation.h>
|
||||
#include <pcl/ModelCoefficients.h>
|
||||
#include <pcl/io/pcd_io.h>
|
||||
#include <pcl/point_types.h>
|
||||
#include <pcl/segmentation/sac_segmentation.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace Reen;
|
||||
|
||||
#if defined(HAVE_PCL_FILTERS)
|
||||
using pcl::PointXYZ;
|
||||
using pcl::PointNormal;
|
||||
using pcl::PointCloud;
|
||||
using pcl::PointNormal;
|
||||
using pcl::PointXYZ;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PCL_SEGMENTATION)
|
||||
Segmentation::Segmentation(const Points::PointKernel& pts, std::list<std::vector<int> >& clusters)
|
||||
: myPoints(pts)
|
||||
, myClusters(clusters)
|
||||
{
|
||||
}
|
||||
Segmentation::Segmentation(const Points::PointKernel& pts, std::list<std::vector<int>>& clusters)
|
||||
: myPoints(pts)
|
||||
, myClusters(clusters)
|
||||
{}
|
||||
|
||||
void Segmentation::perform(int ksearch)
|
||||
{
|
||||
@@ -69,16 +68,18 @@ void Segmentation::perform(int ksearch)
|
||||
pcl::SACSegmentationFromNormals<PointXYZ, pcl::Normal> seg;
|
||||
pcl::ExtractIndices<PointXYZ> extract;
|
||||
pcl::ExtractIndices<pcl::Normal> extract_normals;
|
||||
pcl::search::KdTree<PointXYZ>::Ptr tree (new pcl::search::KdTree<PointXYZ> ());
|
||||
pcl::search::KdTree<PointXYZ>::Ptr tree(new pcl::search::KdTree<PointXYZ>());
|
||||
|
||||
// Datasets
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud (new pcl::PointCloud<PointXYZ>);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<PointXYZ>);
|
||||
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud_filtered2 (new pcl::PointCloud<PointXYZ>);
|
||||
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2 (new pcl::PointCloud<pcl::Normal>);
|
||||
pcl::ModelCoefficients::Ptr coefficients_plane (new pcl::ModelCoefficients), coefficients_cylinder (new pcl::ModelCoefficients);
|
||||
pcl::PointIndices::Ptr inliers_plane (new pcl::PointIndices), inliers_cylinder (new pcl::PointIndices);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud(new pcl::PointCloud<PointXYZ>);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<PointXYZ>);
|
||||
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud_filtered2(new pcl::PointCloud<PointXYZ>);
|
||||
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2(new pcl::PointCloud<pcl::Normal>);
|
||||
pcl::ModelCoefficients::Ptr coefficients_plane(new pcl::ModelCoefficients),
|
||||
coefficients_cylinder(new pcl::ModelCoefficients);
|
||||
pcl::PointIndices::Ptr inliers_plane(new pcl::PointIndices),
|
||||
inliers_cylinder(new pcl::PointIndices);
|
||||
|
||||
// Copy the points
|
||||
cloud->reserve(myPoints.size());
|
||||
@@ -86,97 +87,96 @@ void Segmentation::perform(int ksearch)
|
||||
cloud->push_back(pcl::PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
|
||||
cloud->width = int (cloud->points.size ());
|
||||
cloud->width = int(cloud->points.size());
|
||||
cloud->height = 1;
|
||||
|
||||
// Build a passthrough filter to remove spurious NaNs
|
||||
pass.setInputCloud (cloud);
|
||||
pass.setFilterFieldName ("z");
|
||||
pass.setFilterLimits (0, 1.5);
|
||||
pass.filter (*cloud_filtered);
|
||||
pass.setInputCloud(cloud);
|
||||
pass.setFilterFieldName("z");
|
||||
pass.setFilterLimits(0, 1.5);
|
||||
pass.filter(*cloud_filtered);
|
||||
|
||||
// Estimate point normals
|
||||
ne.setSearchMethod (tree);
|
||||
ne.setInputCloud (cloud_filtered);
|
||||
ne.setKSearch (ksearch);
|
||||
ne.compute (*cloud_normals);
|
||||
ne.setSearchMethod(tree);
|
||||
ne.setInputCloud(cloud_filtered);
|
||||
ne.setKSearch(ksearch);
|
||||
ne.compute(*cloud_normals);
|
||||
|
||||
// Create the segmentation object for the planar model and set all the parameters
|
||||
seg.setOptimizeCoefficients (true);
|
||||
seg.setModelType (pcl::SACMODEL_NORMAL_PLANE);
|
||||
seg.setNormalDistanceWeight (0.1);
|
||||
seg.setMethodType (pcl::SAC_RANSAC);
|
||||
seg.setMaxIterations (100);
|
||||
seg.setDistanceThreshold (0.03);
|
||||
seg.setInputCloud (cloud_filtered);
|
||||
seg.setInputNormals (cloud_normals);
|
||||
seg.setOptimizeCoefficients(true);
|
||||
seg.setModelType(pcl::SACMODEL_NORMAL_PLANE);
|
||||
seg.setNormalDistanceWeight(0.1);
|
||||
seg.setMethodType(pcl::SAC_RANSAC);
|
||||
seg.setMaxIterations(100);
|
||||
seg.setDistanceThreshold(0.03);
|
||||
seg.setInputCloud(cloud_filtered);
|
||||
seg.setInputNormals(cloud_normals);
|
||||
|
||||
// Obtain the plane inliers and coefficients
|
||||
seg.segment (*inliers_plane, *coefficients_plane);
|
||||
seg.segment(*inliers_plane, *coefficients_plane);
|
||||
myClusters.push_back(inliers_plane->indices);
|
||||
|
||||
// Extract the planar inliers from the input cloud
|
||||
extract.setInputCloud (cloud_filtered);
|
||||
extract.setIndices (inliers_plane);
|
||||
extract.setNegative (false);
|
||||
extract.setInputCloud(cloud_filtered);
|
||||
extract.setIndices(inliers_plane);
|
||||
extract.setNegative(false);
|
||||
|
||||
// Write the planar inliers to disk
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud_plane (new pcl::PointCloud<PointXYZ> ());
|
||||
extract.filter (*cloud_plane);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud_plane(new pcl::PointCloud<PointXYZ>());
|
||||
extract.filter(*cloud_plane);
|
||||
|
||||
// Remove the planar inliers, extract the rest
|
||||
extract.setNegative (true);
|
||||
extract.filter (*cloud_filtered2);
|
||||
extract_normals.setNegative (true);
|
||||
extract_normals.setInputCloud (cloud_normals);
|
||||
extract_normals.setIndices (inliers_plane);
|
||||
extract_normals.filter (*cloud_normals2);
|
||||
extract.setNegative(true);
|
||||
extract.filter(*cloud_filtered2);
|
||||
extract_normals.setNegative(true);
|
||||
extract_normals.setInputCloud(cloud_normals);
|
||||
extract_normals.setIndices(inliers_plane);
|
||||
extract_normals.filter(*cloud_normals2);
|
||||
|
||||
// Create the segmentation object for cylinder segmentation and set all the parameters
|
||||
seg.setOptimizeCoefficients (true);
|
||||
seg.setModelType (pcl::SACMODEL_CYLINDER);
|
||||
seg.setNormalDistanceWeight (0.1);
|
||||
seg.setMethodType (pcl::SAC_RANSAC);
|
||||
seg.setMaxIterations (10000);
|
||||
seg.setDistanceThreshold (0.05);
|
||||
seg.setRadiusLimits (0, 0.1);
|
||||
seg.setInputCloud (cloud_filtered2);
|
||||
seg.setInputNormals (cloud_normals2);
|
||||
seg.setOptimizeCoefficients(true);
|
||||
seg.setModelType(pcl::SACMODEL_CYLINDER);
|
||||
seg.setNormalDistanceWeight(0.1);
|
||||
seg.setMethodType(pcl::SAC_RANSAC);
|
||||
seg.setMaxIterations(10000);
|
||||
seg.setDistanceThreshold(0.05);
|
||||
seg.setRadiusLimits(0, 0.1);
|
||||
seg.setInputCloud(cloud_filtered2);
|
||||
seg.setInputNormals(cloud_normals2);
|
||||
|
||||
// Obtain the cylinder inliers and coefficients
|
||||
seg.segment (*inliers_cylinder, *coefficients_cylinder);
|
||||
seg.segment(*inliers_cylinder, *coefficients_cylinder);
|
||||
myClusters.push_back(inliers_cylinder->indices);
|
||||
|
||||
// Write the cylinder inliers to disk
|
||||
extract.setInputCloud (cloud_filtered2);
|
||||
extract.setIndices (inliers_cylinder);
|
||||
extract.setNegative (false);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud_cylinder (new pcl::PointCloud<PointXYZ> ());
|
||||
extract.filter (*cloud_cylinder);
|
||||
extract.setInputCloud(cloud_filtered2);
|
||||
extract.setIndices(inliers_cylinder);
|
||||
extract.setNegative(false);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud_cylinder(new pcl::PointCloud<PointXYZ>());
|
||||
extract.filter(*cloud_cylinder);
|
||||
}
|
||||
|
||||
#endif // HAVE_PCL_SEGMENTATION
|
||||
#endif// HAVE_PCL_SEGMENTATION
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined (HAVE_PCL_FILTERS)
|
||||
#if defined(HAVE_PCL_FILTERS)
|
||||
NormalEstimation::NormalEstimation(const Points::PointKernel& pts)
|
||||
: myPoints(pts)
|
||||
, kSearch(0)
|
||||
, searchRadius(0)
|
||||
{
|
||||
}
|
||||
: myPoints(pts)
|
||||
, kSearch(0)
|
||||
, searchRadius(0)
|
||||
{}
|
||||
|
||||
void NormalEstimation::perform(std::vector<Base::Vector3d>& normals)
|
||||
{
|
||||
// Copy the points
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud (new pcl::PointCloud<PointXYZ>);
|
||||
pcl::PointCloud<PointXYZ>::Ptr cloud(new pcl::PointCloud<PointXYZ>);
|
||||
cloud->reserve(myPoints.size());
|
||||
for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
cloud->push_back(pcl::PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
|
||||
cloud->width = int (cloud->points.size ());
|
||||
cloud->width = int(cloud->points.size());
|
||||
cloud->height = 1;
|
||||
|
||||
#if 0
|
||||
@@ -190,22 +190,26 @@ void NormalEstimation::perform(std::vector<Base::Vector3d>& normals)
|
||||
#endif
|
||||
|
||||
// Estimate point normals
|
||||
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
|
||||
pcl::search::KdTree<PointXYZ>::Ptr tree (new pcl::search::KdTree<PointXYZ> ());
|
||||
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
|
||||
pcl::search::KdTree<PointXYZ>::Ptr tree(new pcl::search::KdTree<PointXYZ>());
|
||||
pcl::NormalEstimation<PointXYZ, pcl::Normal> ne;
|
||||
ne.setSearchMethod (tree);
|
||||
//ne.setInputCloud (cloud_filtered);
|
||||
ne.setInputCloud (cloud);
|
||||
if (kSearch > 0)
|
||||
ne.setKSearch (kSearch);
|
||||
if (searchRadius > 0)
|
||||
ne.setRadiusSearch (searchRadius);
|
||||
ne.compute (*cloud_normals);
|
||||
ne.setSearchMethod(tree);
|
||||
// ne.setInputCloud (cloud_filtered);
|
||||
ne.setInputCloud(cloud);
|
||||
if (kSearch > 0) {
|
||||
ne.setKSearch(kSearch);
|
||||
}
|
||||
if (searchRadius > 0) {
|
||||
ne.setRadiusSearch(searchRadius);
|
||||
}
|
||||
ne.compute(*cloud_normals);
|
||||
|
||||
normals.reserve(cloud_normals->size());
|
||||
for (pcl::PointCloud<pcl::Normal>::const_iterator it = cloud_normals->begin(); it != cloud_normals->end(); ++it) {
|
||||
for (pcl::PointCloud<pcl::Normal>::const_iterator it = cloud_normals->begin();
|
||||
it != cloud_normals->end();
|
||||
++it) {
|
||||
normals.push_back(Base::Vector3d(it->normal_x, it->normal_y, it->normal_z));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_PCL_FILTERS
|
||||
#endif// HAVE_PCL_FILTERS
|
||||
|
||||
@@ -29,22 +29,26 @@
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
|
||||
namespace Points {class PointKernel;}
|
||||
namespace Points
|
||||
{
|
||||
class PointKernel;
|
||||
}
|
||||
|
||||
namespace Reen {
|
||||
namespace Reen
|
||||
{
|
||||
|
||||
class Segmentation
|
||||
{
|
||||
public:
|
||||
Segmentation(const Points::PointKernel&, std::list<std::vector<int> >& clusters);
|
||||
Segmentation(const Points::PointKernel&, std::list<std::vector<int>>& clusters);
|
||||
/** \brief Set the number of k nearest neighbors to use for the normal estimation.
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch);
|
||||
|
||||
private:
|
||||
const Points::PointKernel& myPoints;
|
||||
std::list<std::vector<int> >& myClusters;
|
||||
std::list<std::vector<int>>& myClusters;
|
||||
};
|
||||
|
||||
class NormalEstimation
|
||||
@@ -52,24 +56,25 @@ class NormalEstimation
|
||||
public:
|
||||
explicit NormalEstimation(const Points::PointKernel&);
|
||||
/** \brief Set the number of k nearest neighbors to use for the feature estimation.
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
inline void
|
||||
setKSearch (int k) { kSearch = k; }
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
inline void setKSearch(int k)
|
||||
{
|
||||
kSearch = k;
|
||||
}
|
||||
|
||||
/** \brief Set the sphere radius that is to be used for determining the nearest neighbors used for the feature
|
||||
* estimation.
|
||||
* \param[in] radius the sphere radius used as the maximum distance to consider a point a neighbor
|
||||
*/
|
||||
inline void
|
||||
setSearchRadius (double radius)
|
||||
/** \brief Set the sphere radius that is to be used for determining the nearest neighbors used
|
||||
* for the feature estimation. \param[in] radius the sphere radius used as the maximum distance
|
||||
* to consider a point a neighbor
|
||||
*/
|
||||
inline void setSearchRadius(double radius)
|
||||
{
|
||||
searchRadius = radius;
|
||||
}
|
||||
|
||||
/** \brief Perform the normal estimation.
|
||||
* \param[out] the estimated normals
|
||||
*/
|
||||
* \param[out] the estimated normals
|
||||
*/
|
||||
void perform(std::vector<Base::Vector3d>& normals);
|
||||
|
||||
private:
|
||||
@@ -78,7 +83,6 @@ private:
|
||||
double searchRadius;
|
||||
};
|
||||
|
||||
} // namespace Reen
|
||||
|
||||
#endif // REEN_SEGMENTATION_H
|
||||
}// namespace Reen
|
||||
|
||||
#endif// REEN_SEGMENTATION_H
|
||||
|
||||
@@ -23,36 +23,36 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Mod/Points/App/Points.h>
|
||||
#include <Mod/Mesh/App/Mesh.h>
|
||||
#include <Mod/Mesh/App/Core/Algorithm.h>
|
||||
#include <Mod/Mesh/App/Core/Elements.h>
|
||||
#include <Mod/Mesh/App/Core/MeshKernel.h>
|
||||
#include <Mod/Mesh/App/Mesh.h>
|
||||
#include <Mod/Points/App/Points.h>
|
||||
|
||||
#include "SurfaceTriangulation.h"
|
||||
|
||||
|
||||
// http://svn.pointclouds.org/pcl/tags/pcl-1.5.1/test/
|
||||
#if defined(HAVE_PCL_SURFACE)
|
||||
# include <boost/random.hpp>
|
||||
# include <boost/math/special_functions/fpclassify.hpp>
|
||||
# include <pcl/pcl_config.h>
|
||||
# include <pcl/point_types.h>
|
||||
# include <pcl/features/normal_3d.h>
|
||||
# include <pcl/surface/mls.h>
|
||||
# include <pcl/point_traits.h>
|
||||
# include <pcl/surface/gp3.h>
|
||||
# include <pcl/surface/grid_projection.h>
|
||||
# include <pcl/surface/poisson.h>
|
||||
# include <pcl/surface/organized_fast_mesh.h>
|
||||
# include <pcl/surface/marching_cubes_rbf.h>
|
||||
# include <pcl/surface/marching_cubes_hoppe.h>
|
||||
# include <pcl/surface/ear_clipping.h>
|
||||
# include <pcl/common/common.h>
|
||||
# include <pcl/common/io.h>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <pcl/common/common.h>
|
||||
#include <pcl/common/io.h>
|
||||
#include <pcl/features/normal_3d.h>
|
||||
#include <pcl/pcl_config.h>
|
||||
#include <pcl/point_traits.h>
|
||||
#include <pcl/point_types.h>
|
||||
#include <pcl/surface/ear_clipping.h>
|
||||
#include <pcl/surface/gp3.h>
|
||||
#include <pcl/surface/grid_projection.h>
|
||||
#include <pcl/surface/marching_cubes_hoppe.h>
|
||||
#include <pcl/surface/marching_cubes_rbf.h>
|
||||
#include <pcl/surface/mls.h>
|
||||
#include <pcl/surface/organized_fast_mesh.h>
|
||||
#include <pcl/surface/poisson.h>
|
||||
|
||||
#ifndef PCL_REVISION_VERSION
|
||||
# define PCL_REVISION_VERSION 0
|
||||
#define PCL_REVISION_VERSION 0
|
||||
#endif
|
||||
|
||||
using namespace pcl;
|
||||
@@ -64,84 +64,86 @@ using namespace Reen;
|
||||
// http://www.ics.uci.edu/~gopi/PAPERS/Euro00.pdf
|
||||
// http://www.ics.uci.edu/~gopi/PAPERS/CGMV.pdf
|
||||
SurfaceTriangulation::SurfaceTriangulation(const Points::PointKernel& pts, Mesh::MeshObject& mesh)
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
, mu(0)
|
||||
, searchRadius(0)
|
||||
{
|
||||
}
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
, mu(0)
|
||||
, searchRadius(0)
|
||||
{}
|
||||
|
||||
void SurfaceTriangulation::perform(int ksearch)
|
||||
{
|
||||
PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointXYZ>::Ptr tree;
|
||||
search::KdTree<PointNormal>::Ptr tree2;
|
||||
|
||||
cloud->reserve(myPoints.size());
|
||||
for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y)
|
||||
&& !boost::math::isnan(it->z)) {
|
||||
cloud->push_back(PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointXYZ> (false));
|
||||
tree->setInputCloud (cloud);
|
||||
tree.reset(new search::KdTree<PointXYZ>(false));
|
||||
tree->setInputCloud(cloud);
|
||||
|
||||
// Normal estimation
|
||||
NormalEstimation<PointXYZ, Normal> n;
|
||||
PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
|
||||
n.setInputCloud (cloud);
|
||||
//n.setIndices (indices[B);
|
||||
n.setSearchMethod (tree);
|
||||
n.setKSearch (ksearch);
|
||||
n.compute (*normals);
|
||||
PointCloud<Normal>::Ptr normals(new PointCloud<Normal>());
|
||||
n.setInputCloud(cloud);
|
||||
// n.setIndices (indices[B);
|
||||
n.setSearchMethod(tree);
|
||||
n.setKSearch(ksearch);
|
||||
n.compute(*normals);
|
||||
|
||||
// Concatenate XYZ and normal information
|
||||
pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
|
||||
pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
|
||||
|
||||
// Create search tree
|
||||
tree2.reset (new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud (cloud_with_normals);
|
||||
tree2.reset(new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud(cloud_with_normals);
|
||||
|
||||
// Init objects
|
||||
GreedyProjectionTriangulation<PointNormal> gp3;
|
||||
|
||||
// Set parameters
|
||||
gp3.setInputCloud (cloud_with_normals);
|
||||
gp3.setSearchMethod (tree2);
|
||||
gp3.setSearchRadius (searchRadius);
|
||||
gp3.setMu (mu);
|
||||
gp3.setMaximumNearestNeighbors (100);
|
||||
gp3.setMaximumSurfaceAngle(M_PI/4); // 45 degrees
|
||||
gp3.setMinimumAngle(M_PI/18); // 10 degrees
|
||||
gp3.setMaximumAngle(2*M_PI/3); // 120 degrees
|
||||
gp3.setInputCloud(cloud_with_normals);
|
||||
gp3.setSearchMethod(tree2);
|
||||
gp3.setSearchRadius(searchRadius);
|
||||
gp3.setMu(mu);
|
||||
gp3.setMaximumNearestNeighbors(100);
|
||||
gp3.setMaximumSurfaceAngle(M_PI / 4);// 45 degrees
|
||||
gp3.setMinimumAngle(M_PI / 18); // 10 degrees
|
||||
gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees
|
||||
gp3.setNormalConsistency(false);
|
||||
gp3.setConsistentVertexOrdering(true);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
gp3.reconstruct (mesh);
|
||||
gp3.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
|
||||
// Additional vertex information
|
||||
//std::vector<int> parts = gp3.getPartIDs();
|
||||
//std::vector<int> states = gp3.getPointStates();
|
||||
// std::vector<int> parts = gp3.getPartIDs();
|
||||
// std::vector<int> states = gp3.getPointStates();
|
||||
}
|
||||
|
||||
void SurfaceTriangulation::perform(const std::vector<Base::Vector3f>& normals)
|
||||
{
|
||||
if (myPoints.size() != normals.size())
|
||||
if (myPoints.size() != normals.size()) {
|
||||
throw Base::RuntimeError("Number of points doesn't match with number of normals");
|
||||
}
|
||||
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointNormal>::Ptr tree;
|
||||
|
||||
cloud_with_normals->reserve(myPoints.size());
|
||||
std::size_t num_points = myPoints.size();
|
||||
const std::vector<Base::Vector3f>& points = myPoints.getBasicPoints();
|
||||
for (std::size_t index=0; index<num_points; index++) {
|
||||
for (std::size_t index = 0; index < num_points; index++) {
|
||||
const Base::Vector3f& p = points[index];
|
||||
const Base::Vector3f& n = normals[index];
|
||||
if (!boost::math::isnan(p.x) && !boost::math::isnan(p.y) && !boost::math::isnan(p.z)) {
|
||||
@@ -157,33 +159,33 @@ void SurfaceTriangulation::perform(const std::vector<Base::Vector3f>& normals)
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud (cloud_with_normals);
|
||||
tree.reset(new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud(cloud_with_normals);
|
||||
|
||||
// Init objects
|
||||
GreedyProjectionTriangulation<PointNormal> gp3;
|
||||
|
||||
// Set parameters
|
||||
gp3.setInputCloud (cloud_with_normals);
|
||||
gp3.setSearchMethod (tree);
|
||||
gp3.setSearchRadius (searchRadius);
|
||||
gp3.setMu (mu);
|
||||
gp3.setMaximumNearestNeighbors (100);
|
||||
gp3.setMaximumSurfaceAngle(M_PI/4); // 45 degrees
|
||||
gp3.setMinimumAngle(M_PI/18); // 10 degrees
|
||||
gp3.setMaximumAngle(2*M_PI/3); // 120 degrees
|
||||
gp3.setInputCloud(cloud_with_normals);
|
||||
gp3.setSearchMethod(tree);
|
||||
gp3.setSearchRadius(searchRadius);
|
||||
gp3.setMu(mu);
|
||||
gp3.setMaximumNearestNeighbors(100);
|
||||
gp3.setMaximumSurfaceAngle(M_PI / 4);// 45 degrees
|
||||
gp3.setMinimumAngle(M_PI / 18); // 10 degrees
|
||||
gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees
|
||||
gp3.setNormalConsistency(true);
|
||||
gp3.setConsistentVertexOrdering(true);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
gp3.reconstruct (mesh);
|
||||
gp3.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
|
||||
// Additional vertex information
|
||||
//std::vector<int> parts = gp3.getPartIDs();
|
||||
//std::vector<int> states = gp3.getPointStates();
|
||||
// std::vector<int> parts = gp3.getPartIDs();
|
||||
// std::vector<int> states = gp3.getPointStates();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -191,79 +193,84 @@ void SurfaceTriangulation::perform(const std::vector<Base::Vector3f>& normals)
|
||||
// See
|
||||
// http://www.cs.jhu.edu/~misha/Code/PoissonRecon/Version8.0/
|
||||
PoissonReconstruction::PoissonReconstruction(const Points::PointKernel& pts, Mesh::MeshObject& mesh)
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
, depth(-1)
|
||||
, solverDivide(-1)
|
||||
, samplesPerNode(-1.0f)
|
||||
{
|
||||
}
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
, depth(-1)
|
||||
, solverDivide(-1)
|
||||
, samplesPerNode(-1.0f)
|
||||
{}
|
||||
|
||||
void PoissonReconstruction::perform(int ksearch)
|
||||
{
|
||||
PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointXYZ>::Ptr tree;
|
||||
search::KdTree<PointNormal>::Ptr tree2;
|
||||
|
||||
cloud->reserve(myPoints.size());
|
||||
for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y)
|
||||
&& !boost::math::isnan(it->z)) {
|
||||
cloud->push_back(PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointXYZ> (false));
|
||||
tree->setInputCloud (cloud);
|
||||
tree.reset(new search::KdTree<PointXYZ>(false));
|
||||
tree->setInputCloud(cloud);
|
||||
|
||||
// Normal estimation
|
||||
NormalEstimation<PointXYZ, Normal> n;
|
||||
PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
|
||||
n.setInputCloud (cloud);
|
||||
//n.setIndices (indices[B);
|
||||
n.setSearchMethod (tree);
|
||||
n.setKSearch (ksearch);
|
||||
n.compute (*normals);
|
||||
PointCloud<Normal>::Ptr normals(new PointCloud<Normal>());
|
||||
n.setInputCloud(cloud);
|
||||
// n.setIndices (indices[B);
|
||||
n.setSearchMethod(tree);
|
||||
n.setKSearch(ksearch);
|
||||
n.compute(*normals);
|
||||
|
||||
// Concatenate XYZ and normal information
|
||||
pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
|
||||
pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
|
||||
|
||||
// Create search tree
|
||||
tree2.reset (new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud (cloud_with_normals);
|
||||
tree2.reset(new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud(cloud_with_normals);
|
||||
|
||||
// Init objects
|
||||
Poisson<PointNormal> poisson;
|
||||
|
||||
// Set parameters
|
||||
poisson.setInputCloud (cloud_with_normals);
|
||||
poisson.setSearchMethod (tree2);
|
||||
if (depth >= 1)
|
||||
poisson.setInputCloud(cloud_with_normals);
|
||||
poisson.setSearchMethod(tree2);
|
||||
if (depth >= 1) {
|
||||
poisson.setDepth(depth);
|
||||
if (solverDivide >= 1)
|
||||
}
|
||||
if (solverDivide >= 1) {
|
||||
poisson.setSolverDivide(solverDivide);
|
||||
if (samplesPerNode >= 1.0f)
|
||||
}
|
||||
if (samplesPerNode >= 1.0f) {
|
||||
poisson.setSamplesPerNode(samplesPerNode);
|
||||
}
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
poisson.reconstruct (mesh);
|
||||
poisson.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
}
|
||||
|
||||
void PoissonReconstruction::perform(const std::vector<Base::Vector3f>& normals)
|
||||
{
|
||||
if (myPoints.size() != normals.size())
|
||||
if (myPoints.size() != normals.size()) {
|
||||
throw Base::RuntimeError("Number of points doesn't match with number of normals");
|
||||
}
|
||||
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointNormal>::Ptr tree;
|
||||
|
||||
cloud_with_normals->reserve(myPoints.size());
|
||||
std::size_t num_points = myPoints.size();
|
||||
const std::vector<Base::Vector3f>& points = myPoints.getBasicPoints();
|
||||
for (std::size_t index=0; index<num_points; index++) {
|
||||
for (std::size_t index = 0; index < num_points; index++) {
|
||||
const Base::Vector3f& p = points[index];
|
||||
const Base::Vector3f& n = normals[index];
|
||||
if (!boost::math::isnan(p.x) && !boost::math::isnan(p.y) && !boost::math::isnan(p.z)) {
|
||||
@@ -279,25 +286,28 @@ void PoissonReconstruction::perform(const std::vector<Base::Vector3f>& normals)
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud (cloud_with_normals);
|
||||
tree.reset(new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud(cloud_with_normals);
|
||||
|
||||
// Init objects
|
||||
Poisson<PointNormal> poisson;
|
||||
|
||||
// Set parameters
|
||||
poisson.setInputCloud (cloud_with_normals);
|
||||
poisson.setSearchMethod (tree);
|
||||
if (depth >= 1)
|
||||
poisson.setInputCloud(cloud_with_normals);
|
||||
poisson.setSearchMethod(tree);
|
||||
if (depth >= 1) {
|
||||
poisson.setDepth(depth);
|
||||
if (solverDivide >= 1)
|
||||
}
|
||||
if (solverDivide >= 1) {
|
||||
poisson.setSolverDivide(solverDivide);
|
||||
if (samplesPerNode >= 1.0f)
|
||||
}
|
||||
if (samplesPerNode >= 1.0f) {
|
||||
poisson.setSamplesPerNode(samplesPerNode);
|
||||
}
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
poisson.reconstruct (mesh);
|
||||
poisson.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
}
|
||||
@@ -305,43 +315,44 @@ void PoissonReconstruction::perform(const std::vector<Base::Vector3f>& normals)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
GridReconstruction::GridReconstruction(const Points::PointKernel& pts, Mesh::MeshObject& mesh)
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
{
|
||||
}
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
{}
|
||||
|
||||
void GridReconstruction::perform(int ksearch)
|
||||
{
|
||||
PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointXYZ>::Ptr tree;
|
||||
search::KdTree<PointNormal>::Ptr tree2;
|
||||
|
||||
cloud->reserve(myPoints.size());
|
||||
for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y)
|
||||
&& !boost::math::isnan(it->z)) {
|
||||
cloud->push_back(PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointXYZ> (false));
|
||||
tree->setInputCloud (cloud);
|
||||
tree.reset(new search::KdTree<PointXYZ>(false));
|
||||
tree->setInputCloud(cloud);
|
||||
|
||||
// Normal estimation
|
||||
NormalEstimation<PointXYZ, Normal> n;
|
||||
PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
|
||||
n.setInputCloud (cloud);
|
||||
//n.setIndices (indices[B);
|
||||
n.setSearchMethod (tree);
|
||||
n.setKSearch (ksearch);
|
||||
n.compute (*normals);
|
||||
PointCloud<Normal>::Ptr normals(new PointCloud<Normal>());
|
||||
n.setInputCloud(cloud);
|
||||
// n.setIndices (indices[B);
|
||||
n.setSearchMethod(tree);
|
||||
n.setKSearch(ksearch);
|
||||
n.compute(*normals);
|
||||
|
||||
// Concatenate XYZ and normal information
|
||||
pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
|
||||
pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
|
||||
|
||||
// Create search tree
|
||||
tree2.reset (new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud (cloud_with_normals);
|
||||
tree2.reset(new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud(cloud_with_normals);
|
||||
|
||||
// Init objects
|
||||
GridProjection<PointNormal> grid;
|
||||
@@ -351,28 +362,29 @@ void GridReconstruction::perform(int ksearch)
|
||||
grid.setPaddingSize(3);
|
||||
grid.setNearestNeighborNum(100);
|
||||
grid.setMaxBinarySearchLevel(10);
|
||||
grid.setInputCloud (cloud_with_normals);
|
||||
grid.setSearchMethod (tree2);
|
||||
grid.setInputCloud(cloud_with_normals);
|
||||
grid.setSearchMethod(tree2);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
grid.reconstruct (mesh);
|
||||
grid.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
}
|
||||
|
||||
void GridReconstruction::perform(const std::vector<Base::Vector3f>& normals)
|
||||
{
|
||||
if (myPoints.size() != normals.size())
|
||||
if (myPoints.size() != normals.size()) {
|
||||
throw Base::RuntimeError("Number of points doesn't match with number of normals");
|
||||
}
|
||||
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointNormal>::Ptr tree;
|
||||
|
||||
cloud_with_normals->reserve(myPoints.size());
|
||||
std::size_t num_points = myPoints.size();
|
||||
const std::vector<Base::Vector3f>& points = myPoints.getBasicPoints();
|
||||
for (std::size_t index=0; index<num_points; index++) {
|
||||
for (std::size_t index = 0; index < num_points; index++) {
|
||||
const Base::Vector3f& p = points[index];
|
||||
const Base::Vector3f& n = normals[index];
|
||||
if (!boost::math::isnan(p.x) && !boost::math::isnan(p.y) && !boost::math::isnan(p.z)) {
|
||||
@@ -388,8 +400,8 @@ void GridReconstruction::perform(const std::vector<Base::Vector3f>& normals)
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud (cloud_with_normals);
|
||||
tree.reset(new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud(cloud_with_normals);
|
||||
|
||||
// Init objects
|
||||
GridProjection<PointNormal> grid;
|
||||
@@ -399,36 +411,39 @@ void GridReconstruction::perform(const std::vector<Base::Vector3f>& normals)
|
||||
grid.setPaddingSize(3);
|
||||
grid.setNearestNeighborNum(100);
|
||||
grid.setMaxBinarySearchLevel(10);
|
||||
grid.setInputCloud (cloud_with_normals);
|
||||
grid.setSearchMethod (tree);
|
||||
grid.setInputCloud(cloud_with_normals);
|
||||
grid.setSearchMethod(tree);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
grid.reconstruct (mesh);
|
||||
grid.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ImageTriangulation::ImageTriangulation(int width, int height, const Points::PointKernel& pts, Mesh::MeshObject& mesh)
|
||||
: width(width)
|
||||
, height(height)
|
||||
, myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
{
|
||||
}
|
||||
ImageTriangulation::ImageTriangulation(int width,
|
||||
int height,
|
||||
const Points::PointKernel& pts,
|
||||
Mesh::MeshObject& mesh)
|
||||
: width(width)
|
||||
, height(height)
|
||||
, myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
{}
|
||||
|
||||
void ImageTriangulation::perform()
|
||||
{
|
||||
if (myPoints.size() != static_cast<std::size_t>(width * height))
|
||||
if (myPoints.size() != static_cast<std::size_t>(width * height)) {
|
||||
throw Base::RuntimeError("Number of points doesn't match with given width and height");
|
||||
}
|
||||
|
||||
//construct dataset
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_organized (new pcl::PointCloud<pcl::PointXYZ> ());
|
||||
// construct dataset
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_organized(new pcl::PointCloud<pcl::PointXYZ>());
|
||||
cloud_organized->width = width;
|
||||
cloud_organized->height = height;
|
||||
cloud_organized->points.resize (cloud_organized->width * cloud_organized->height);
|
||||
cloud_organized->points.resize(cloud_organized->width * cloud_organized->height);
|
||||
|
||||
const std::vector<Base::Vector3f>& points = myPoints.getBasicPoints();
|
||||
|
||||
@@ -446,16 +461,16 @@ void ImageTriangulation::perform()
|
||||
OrganizedFastMesh<PointXYZ> ofm;
|
||||
|
||||
// Set parameters
|
||||
ofm.setInputCloud (cloud_organized);
|
||||
ofm.setInputCloud(cloud_organized);
|
||||
// This parameter is not yet implemented (pcl 1.7)
|
||||
ofm.setMaxEdgeLength (1.5);
|
||||
ofm.setTrianglePixelSize (1);
|
||||
ofm.setTriangulationType (OrganizedFastMesh<PointXYZ>::TRIANGLE_ADAPTIVE_CUT);
|
||||
ofm.setMaxEdgeLength(1.5);
|
||||
ofm.setTrianglePixelSize(1);
|
||||
ofm.setTriangulationType(OrganizedFastMesh<PointXYZ>::TRIANGLE_ADAPTIVE_CUT);
|
||||
ofm.storeShadowedFaces(true);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
ofm.reconstruct (mesh);
|
||||
ofm.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
|
||||
@@ -466,7 +481,7 @@ void ImageTriangulation::perform()
|
||||
MeshCore::MeshAlgorithm meshAlg(kernel);
|
||||
meshAlg.SetPointFlag(MeshCore::MeshPoint::INVALID);
|
||||
std::vector<MeshCore::PointIndex> validPoints;
|
||||
validPoints.reserve(face.size()*3);
|
||||
validPoints.reserve(face.size() * 3);
|
||||
for (MeshCore::MeshFacetArray::_TConstIterator it = face.begin(); it != face.end(); ++it) {
|
||||
validPoints.push_back(it->_aulPoints[0]);
|
||||
validPoints.push_back(it->_aulPoints[1]);
|
||||
@@ -491,75 +506,77 @@ void ImageTriangulation::perform()
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Reen::MarchingCubesRBF::MarchingCubesRBF(const Points::PointKernel& pts, Mesh::MeshObject& mesh)
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
{
|
||||
}
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
{}
|
||||
|
||||
void Reen::MarchingCubesRBF::perform(int ksearch)
|
||||
{
|
||||
PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointXYZ>::Ptr tree;
|
||||
search::KdTree<PointNormal>::Ptr tree2;
|
||||
|
||||
cloud->reserve(myPoints.size());
|
||||
for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y)
|
||||
&& !boost::math::isnan(it->z)) {
|
||||
cloud->push_back(PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointXYZ> (false));
|
||||
tree->setInputCloud (cloud);
|
||||
tree.reset(new search::KdTree<PointXYZ>(false));
|
||||
tree->setInputCloud(cloud);
|
||||
|
||||
// Normal estimation
|
||||
NormalEstimation<PointXYZ, Normal> n;
|
||||
PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
|
||||
n.setInputCloud (cloud);
|
||||
//n.setIndices (indices[B);
|
||||
n.setSearchMethod (tree);
|
||||
n.setKSearch (ksearch);
|
||||
n.compute (*normals);
|
||||
PointCloud<Normal>::Ptr normals(new PointCloud<Normal>());
|
||||
n.setInputCloud(cloud);
|
||||
// n.setIndices (indices[B);
|
||||
n.setSearchMethod(tree);
|
||||
n.setKSearch(ksearch);
|
||||
n.compute(*normals);
|
||||
|
||||
// Concatenate XYZ and normal information
|
||||
pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
|
||||
pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
|
||||
|
||||
// Create search tree
|
||||
tree2.reset (new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud (cloud_with_normals);
|
||||
tree2.reset(new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud(cloud_with_normals);
|
||||
|
||||
// Init objects
|
||||
pcl::MarchingCubesRBF<PointNormal> rbf;
|
||||
|
||||
// Set parameters
|
||||
rbf.setIsoLevel (0);
|
||||
rbf.setGridResolution (60, 60, 60);
|
||||
rbf.setPercentageExtendGrid (0.1f);
|
||||
rbf.setOffSurfaceDisplacement (0.02f);
|
||||
rbf.setIsoLevel(0);
|
||||
rbf.setGridResolution(60, 60, 60);
|
||||
rbf.setPercentageExtendGrid(0.1f);
|
||||
rbf.setOffSurfaceDisplacement(0.02f);
|
||||
|
||||
rbf.setInputCloud (cloud_with_normals);
|
||||
rbf.setSearchMethod (tree2);
|
||||
rbf.setInputCloud(cloud_with_normals);
|
||||
rbf.setSearchMethod(tree2);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
rbf.reconstruct (mesh);
|
||||
rbf.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
}
|
||||
|
||||
void Reen::MarchingCubesRBF::perform(const std::vector<Base::Vector3f>& normals)
|
||||
{
|
||||
if (myPoints.size() != normals.size())
|
||||
if (myPoints.size() != normals.size()) {
|
||||
throw Base::RuntimeError("Number of points doesn't match with number of normals");
|
||||
}
|
||||
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointNormal>::Ptr tree;
|
||||
|
||||
cloud_with_normals->reserve(myPoints.size());
|
||||
std::size_t num_points = myPoints.size();
|
||||
const std::vector<Base::Vector3f>& points = myPoints.getBasicPoints();
|
||||
for (std::size_t index=0; index<num_points; index++) {
|
||||
for (std::size_t index = 0; index < num_points; index++) {
|
||||
const Base::Vector3f& p = points[index];
|
||||
const Base::Vector3f& n = normals[index];
|
||||
if (!boost::math::isnan(p.x) && !boost::math::isnan(p.y) && !boost::math::isnan(p.z)) {
|
||||
@@ -575,25 +592,25 @@ void Reen::MarchingCubesRBF::perform(const std::vector<Base::Vector3f>& normals)
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud (cloud_with_normals);
|
||||
tree.reset(new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud(cloud_with_normals);
|
||||
|
||||
|
||||
// Init objects
|
||||
pcl::MarchingCubesRBF<PointNormal> rbf;
|
||||
|
||||
// Set parameters
|
||||
rbf.setIsoLevel (0);
|
||||
rbf.setGridResolution (60, 60, 60);
|
||||
rbf.setPercentageExtendGrid (0.1f);
|
||||
rbf.setOffSurfaceDisplacement (0.02f);
|
||||
rbf.setIsoLevel(0);
|
||||
rbf.setGridResolution(60, 60, 60);
|
||||
rbf.setPercentageExtendGrid(0.1f);
|
||||
rbf.setOffSurfaceDisplacement(0.02f);
|
||||
|
||||
rbf.setInputCloud (cloud_with_normals);
|
||||
rbf.setSearchMethod (tree);
|
||||
rbf.setInputCloud(cloud_with_normals);
|
||||
rbf.setSearchMethod(tree);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
rbf.reconstruct (mesh);
|
||||
rbf.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
}
|
||||
@@ -601,74 +618,76 @@ void Reen::MarchingCubesRBF::perform(const std::vector<Base::Vector3f>& normals)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Reen::MarchingCubesHoppe::MarchingCubesHoppe(const Points::PointKernel& pts, Mesh::MeshObject& mesh)
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
{
|
||||
}
|
||||
: myPoints(pts)
|
||||
, myMesh(mesh)
|
||||
{}
|
||||
|
||||
void Reen::MarchingCubesHoppe::perform(int ksearch)
|
||||
{
|
||||
PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointXYZ>::Ptr tree;
|
||||
search::KdTree<PointNormal>::Ptr tree2;
|
||||
|
||||
cloud->reserve(myPoints.size());
|
||||
for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
|
||||
if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y)
|
||||
&& !boost::math::isnan(it->z)) {
|
||||
cloud->push_back(PointXYZ(it->x, it->y, it->z));
|
||||
}
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointXYZ> (false));
|
||||
tree->setInputCloud (cloud);
|
||||
tree.reset(new search::KdTree<PointXYZ>(false));
|
||||
tree->setInputCloud(cloud);
|
||||
|
||||
// Normal estimation
|
||||
NormalEstimation<PointXYZ, Normal> n;
|
||||
PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
|
||||
n.setInputCloud (cloud);
|
||||
//n.setIndices (indices[B);
|
||||
n.setSearchMethod (tree);
|
||||
n.setKSearch (ksearch);
|
||||
n.compute (*normals);
|
||||
PointCloud<Normal>::Ptr normals(new PointCloud<Normal>());
|
||||
n.setInputCloud(cloud);
|
||||
// n.setIndices (indices[B);
|
||||
n.setSearchMethod(tree);
|
||||
n.setKSearch(ksearch);
|
||||
n.compute(*normals);
|
||||
|
||||
// Concatenate XYZ and normal information
|
||||
pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
|
||||
pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
|
||||
|
||||
// Create search tree
|
||||
tree2.reset (new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud (cloud_with_normals);
|
||||
tree2.reset(new search::KdTree<PointNormal>);
|
||||
tree2->setInputCloud(cloud_with_normals);
|
||||
|
||||
// Init objects
|
||||
pcl::MarchingCubesHoppe<PointNormal> hoppe;
|
||||
|
||||
// Set parameters
|
||||
hoppe.setIsoLevel (0);
|
||||
hoppe.setGridResolution (60, 60, 60);
|
||||
hoppe.setPercentageExtendGrid (0.1f);
|
||||
hoppe.setIsoLevel(0);
|
||||
hoppe.setGridResolution(60, 60, 60);
|
||||
hoppe.setPercentageExtendGrid(0.1f);
|
||||
|
||||
hoppe.setInputCloud (cloud_with_normals);
|
||||
hoppe.setSearchMethod (tree2);
|
||||
hoppe.setInputCloud(cloud_with_normals);
|
||||
hoppe.setSearchMethod(tree2);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
hoppe.reconstruct (mesh);
|
||||
hoppe.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
}
|
||||
|
||||
void Reen::MarchingCubesHoppe::perform(const std::vector<Base::Vector3f>& normals)
|
||||
{
|
||||
if (myPoints.size() != normals.size())
|
||||
if (myPoints.size() != normals.size()) {
|
||||
throw Base::RuntimeError("Number of points doesn't match with number of normals");
|
||||
}
|
||||
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
|
||||
PointCloud<PointNormal>::Ptr cloud_with_normals(new PointCloud<PointNormal>);
|
||||
search::KdTree<PointNormal>::Ptr tree;
|
||||
|
||||
cloud_with_normals->reserve(myPoints.size());
|
||||
std::size_t num_points = myPoints.size();
|
||||
const std::vector<Base::Vector3f>& points = myPoints.getBasicPoints();
|
||||
for (std::size_t index=0; index<num_points; index++) {
|
||||
for (std::size_t index = 0; index < num_points; index++) {
|
||||
const Base::Vector3f& p = points[index];
|
||||
const Base::Vector3f& n = normals[index];
|
||||
if (!boost::math::isnan(p.x) && !boost::math::isnan(p.y) && !boost::math::isnan(p.z)) {
|
||||
@@ -684,24 +703,24 @@ void Reen::MarchingCubesHoppe::perform(const std::vector<Base::Vector3f>& normal
|
||||
}
|
||||
|
||||
// Create search tree
|
||||
tree.reset (new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud (cloud_with_normals);
|
||||
tree.reset(new search::KdTree<PointNormal>);
|
||||
tree->setInputCloud(cloud_with_normals);
|
||||
|
||||
|
||||
// Init objects
|
||||
pcl::MarchingCubesHoppe<PointNormal> hoppe;
|
||||
|
||||
// Set parameters
|
||||
hoppe.setIsoLevel (0);
|
||||
hoppe.setGridResolution (60, 60, 60);
|
||||
hoppe.setPercentageExtendGrid (0.1f);
|
||||
hoppe.setIsoLevel(0);
|
||||
hoppe.setGridResolution(60, 60, 60);
|
||||
hoppe.setPercentageExtendGrid(0.1f);
|
||||
|
||||
hoppe.setInputCloud (cloud_with_normals);
|
||||
hoppe.setSearchMethod (tree);
|
||||
hoppe.setInputCloud(cloud_with_normals);
|
||||
hoppe.setSearchMethod(tree);
|
||||
|
||||
// Reconstruct
|
||||
PolygonMesh mesh;
|
||||
hoppe.reconstruct (mesh);
|
||||
hoppe.reconstruct(mesh);
|
||||
|
||||
MeshConversion::convert(mesh, myMesh);
|
||||
}
|
||||
@@ -711,10 +730,10 @@ void Reen::MarchingCubesHoppe::perform(const std::vector<Base::Vector3f>& normal
|
||||
void MeshConversion::convert(const pcl::PolygonMesh& pclMesh, Mesh::MeshObject& meshObject)
|
||||
{
|
||||
// number of points
|
||||
size_t nr_points = pclMesh.cloud.width * pclMesh.cloud.height;
|
||||
size_t point_size = pclMesh.cloud.data.size () / nr_points;
|
||||
size_t nr_points = pclMesh.cloud.width * pclMesh.cloud.height;
|
||||
size_t point_size = pclMesh.cloud.data.size() / nr_points;
|
||||
// number of faces for header
|
||||
size_t nr_faces = pclMesh.polygons.size ();
|
||||
size_t nr_faces = pclMesh.polygons.size();
|
||||
|
||||
MeshCore::MeshPointArray points;
|
||||
points.reserve(nr_points);
|
||||
@@ -729,17 +748,20 @@ void MeshConversion::convert(const pcl::PolygonMesh& pclMesh, Mesh::MeshObject&
|
||||
int c = 0;
|
||||
// adding vertex
|
||||
if ((pclMesh.cloud.fields[d].datatype ==
|
||||
#if PCL_VERSION_COMPARE(>,1,6,0)
|
||||
pcl::PCLPointField::FLOAT32) &&
|
||||
#if PCL_VERSION_COMPARE(>, 1, 6, 0)
|
||||
pcl::PCLPointField::FLOAT32)
|
||||
&&
|
||||
#else
|
||||
sensor_msgs::PointField::FLOAT32) &&
|
||||
sensor_msgs::PointField::FLOAT32)
|
||||
&&
|
||||
#endif
|
||||
(pclMesh.cloud.fields[d].name == "x" ||
|
||||
pclMesh.cloud.fields[d].name == "y" ||
|
||||
pclMesh.cloud.fields[d].name == "z"))
|
||||
{
|
||||
(pclMesh.cloud.fields[d].name == "x" || pclMesh.cloud.fields[d].name == "y"
|
||||
|| pclMesh.cloud.fields[d].name == "z")) {
|
||||
float value;
|
||||
memcpy (&value, &pclMesh.cloud.data[i * point_size + pclMesh.cloud.fields[d].offset + c * sizeof (float)], sizeof (float));
|
||||
memcpy(&value,
|
||||
&pclMesh.cloud.data[i * point_size + pclMesh.cloud.fields[d].offset
|
||||
+ c * sizeof(float)],
|
||||
sizeof(float));
|
||||
vertex[xyz] = value;
|
||||
if (++xyz == 3) {
|
||||
points.push_back(vertex);
|
||||
@@ -763,4 +785,4 @@ void MeshConversion::convert(const pcl::PolygonMesh& pclMesh, Mesh::MeshObject&
|
||||
meshObject.harmonizeNormals();
|
||||
}
|
||||
|
||||
#endif // HAVE_PCL_SURFACE
|
||||
#endif// HAVE_PCL_SURFACE
|
||||
|
||||
@@ -28,11 +28,21 @@
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
|
||||
namespace Points {class PointKernel;}
|
||||
namespace Mesh {class MeshObject;}
|
||||
namespace pcl {struct PolygonMesh;}
|
||||
namespace Points
|
||||
{
|
||||
class PointKernel;
|
||||
}
|
||||
namespace Mesh
|
||||
{
|
||||
class MeshObject;
|
||||
}
|
||||
namespace pcl
|
||||
{
|
||||
struct PolygonMesh;
|
||||
}
|
||||
|
||||
namespace Reen {
|
||||
namespace Reen
|
||||
{
|
||||
|
||||
class MeshConversion
|
||||
{
|
||||
@@ -45,27 +55,31 @@ class SurfaceTriangulation
|
||||
public:
|
||||
SurfaceTriangulation(const Points::PointKernel&, Mesh::MeshObject&);
|
||||
/** \brief Set the number of k nearest neighbors to use for the normal estimation.
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch);
|
||||
/** \brief Pass the normals to the points given in the constructor.
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
void perform(const std::vector<Base::Vector3f>& normals);
|
||||
|
||||
/** \brief Set the multiplier of the nearest neighbor distance to obtain the final search radius for each point
|
||||
* (this will make the algorithm adapt to different point densities in the cloud).
|
||||
* \param[in] mu the multiplier
|
||||
*/
|
||||
inline void
|
||||
setMu (double mu) { this->mu = mu; }
|
||||
/** \brief Set the multiplier of the nearest neighbor distance to obtain the final search radius
|
||||
* for each point (this will make the algorithm adapt to different point densities in the
|
||||
* cloud). \param[in] mu the multiplier
|
||||
*/
|
||||
inline void setMu(double mu)
|
||||
{
|
||||
this->mu = mu;
|
||||
}
|
||||
|
||||
/** \brief Set the sphere radius that is to be used for determining the k-nearest neighbors used for triangulating.
|
||||
* \param[in] radius the sphere radius that is to contain all k-nearest neighbors
|
||||
* \note This distance limits the maximum edge length!
|
||||
*/
|
||||
inline void
|
||||
setSearchRadius (double radius) { this->searchRadius = radius; }
|
||||
/** \brief Set the sphere radius that is to be used for determining the k-nearest neighbors used
|
||||
* for triangulating. \param[in] radius the sphere radius that is to contain all k-nearest
|
||||
* neighbors \note This distance limits the maximum edge length!
|
||||
*/
|
||||
inline void setSearchRadius(double radius)
|
||||
{
|
||||
this->searchRadius = radius;
|
||||
}
|
||||
|
||||
private:
|
||||
const Points::PointKernel& myPoints;
|
||||
@@ -79,40 +93,46 @@ class PoissonReconstruction
|
||||
public:
|
||||
PoissonReconstruction(const Points::PointKernel&, Mesh::MeshObject&);
|
||||
/** \brief Set the number of k nearest neighbors to use for the normal estimation.
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch=5);
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch = 5);
|
||||
/** \brief Pass the normals to the points given in the constructor.
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
void perform(const std::vector<Base::Vector3f>& normals);
|
||||
|
||||
/** \brief Set the maximum depth of the tree that will be used for surface reconstruction.
|
||||
* \note Running at depth d corresponds to solving on a voxel grid whose resolution is no larger than
|
||||
* 2^d x 2^d x 2^d. Note that since the reconstructor adapts the octree to the sampling density, the specified
|
||||
* reconstruction depth is only an upper bound.
|
||||
* \param[in] depth the depth parameter
|
||||
*/
|
||||
inline void
|
||||
setDepth (int depth) { this->depth = depth; }
|
||||
* \note Running at depth d corresponds to solving on a voxel grid whose resolution is no larger
|
||||
* than 2^d x 2^d x 2^d. Note that since the reconstructor adapts the octree to the sampling
|
||||
* density, the specified reconstruction depth is only an upper bound. \param[in] depth the
|
||||
* depth parameter
|
||||
*/
|
||||
inline void setDepth(int depth)
|
||||
{
|
||||
this->depth = depth;
|
||||
}
|
||||
|
||||
/** \brief Set the depth at which a block Gauss-Seidel solver is used to solve the Laplacian equation
|
||||
* \note Using this parameter helps reduce the memory overhead at the cost of a small increase in
|
||||
* reconstruction time. (In practice, we have found that for reconstructions of depth 9 or higher a subdivide
|
||||
* depth of 7 or 8 can greatly reduce the memory usage.)
|
||||
* \param[in] solver_divide the given parameter value
|
||||
*/
|
||||
inline void
|
||||
setSolverDivide (int solverDivide) { this->solverDivide = solverDivide; }
|
||||
/** \brief Set the depth at which a block Gauss-Seidel solver is used to solve the Laplacian
|
||||
* equation \note Using this parameter helps reduce the memory overhead at the cost of a small
|
||||
* increase in reconstruction time. (In practice, we have found that for reconstructions of
|
||||
* depth 9 or higher a subdivide depth of 7 or 8 can greatly reduce the memory usage.)
|
||||
* \param[in] solver_divide the given parameter value
|
||||
*/
|
||||
inline void setSolverDivide(int solverDivide)
|
||||
{
|
||||
this->solverDivide = solverDivide;
|
||||
}
|
||||
|
||||
/** \brief Set the minimum number of sample points that should fall within an octree node as the octree
|
||||
* construction is adapted to sampling density
|
||||
* \note For noise-free samples, small values in the range [1.0 - 5.0] can be used. For more noisy samples,
|
||||
* larger values in the range [15.0 - 20.0] may be needed to provide a smoother, noise-reduced, reconstruction.
|
||||
* \param[in] samples_per_node the given parameter value
|
||||
*/
|
||||
inline void
|
||||
setSamplesPerNode(float samplesPerNode) { this->samplesPerNode = samplesPerNode; }
|
||||
/** \brief Set the minimum number of sample points that should fall within an octree node as the
|
||||
* octree construction is adapted to sampling density \note For noise-free samples, small values
|
||||
* in the range [1.0 - 5.0] can be used. For more noisy samples, larger values in the range
|
||||
* [15.0 - 20.0] may be needed to provide a smoother, noise-reduced, reconstruction. \param[in]
|
||||
* samples_per_node the given parameter value
|
||||
*/
|
||||
inline void setSamplesPerNode(float samplesPerNode)
|
||||
{
|
||||
this->samplesPerNode = samplesPerNode;
|
||||
}
|
||||
|
||||
private:
|
||||
const Points::PointKernel& myPoints;
|
||||
@@ -127,12 +147,12 @@ class GridReconstruction
|
||||
public:
|
||||
GridReconstruction(const Points::PointKernel&, Mesh::MeshObject&);
|
||||
/** \brief Set the number of k nearest neighbors to use for the normal estimation.
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch=5);
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch = 5);
|
||||
/** \brief Pass the normals to the points given in the constructor.
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
void perform(const std::vector<Base::Vector3f>& normals);
|
||||
|
||||
private:
|
||||
@@ -157,12 +177,12 @@ class MarchingCubesRBF
|
||||
public:
|
||||
MarchingCubesRBF(const Points::PointKernel&, Mesh::MeshObject&);
|
||||
/** \brief Set the number of k nearest neighbors to use for the normal estimation.
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch=5);
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch = 5);
|
||||
/** \brief Pass the normals to the points given in the constructor.
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
void perform(const std::vector<Base::Vector3f>& normals);
|
||||
|
||||
private:
|
||||
@@ -175,12 +195,12 @@ class MarchingCubesHoppe
|
||||
public:
|
||||
MarchingCubesHoppe(const Points::PointKernel&, Mesh::MeshObject&);
|
||||
/** \brief Set the number of k nearest neighbors to use for the normal estimation.
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch=5);
|
||||
* \param[in] k the number of k-nearest neighbors
|
||||
*/
|
||||
void perform(int ksearch = 5);
|
||||
/** \brief Pass the normals to the points given in the constructor.
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
* \param[in] normals the normals to the given points.
|
||||
*/
|
||||
void perform(const std::vector<Base::Vector3f>& normals);
|
||||
|
||||
private:
|
||||
@@ -188,7 +208,6 @@ private:
|
||||
Mesh::MeshObject& myMesh;
|
||||
};
|
||||
|
||||
} // namespace Reen
|
||||
|
||||
#endif // REEN_SURFACETRIANGULATION_H
|
||||
}// namespace Reen
|
||||
|
||||
#endif// REEN_SURFACETRIANGULATION_H
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
#***************************************************************************
|
||||
#* Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
|
||||
#* *
|
||||
#* This file is part of the FreeCAD CAx development system. *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* FreeCAD is distributed in the hope that it will be useful, *
|
||||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
#* GNU Lesser General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with FreeCAD; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************/
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * FreeCAD is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with FreeCAD; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
# ReverseEngineering gui init module
|
||||
#
|
||||
@@ -28,10 +28,14 @@
|
||||
# runs when the gui is up
|
||||
|
||||
|
||||
class ReverseEngineeringWorkbench ( Workbench ):
|
||||
class ReverseEngineeringWorkbench(Workbench):
|
||||
"ReverseEngineering workbench object"
|
||||
|
||||
def __init__(self):
|
||||
self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/ReverseEngineering/Resources/icons/ReverseEngineeringWorkbench.svg"
|
||||
self.__class__.Icon = (
|
||||
FreeCAD.getResourceDir()
|
||||
+ "Mod/ReverseEngineering/Resources/icons/ReverseEngineeringWorkbench.svg"
|
||||
)
|
||||
self.__class__.MenuText = "Reverse Engineering"
|
||||
self.__class__.ToolTip = "Reverse Engineering workbench"
|
||||
|
||||
@@ -39,7 +43,9 @@ class ReverseEngineeringWorkbench ( Workbench ):
|
||||
# load the module
|
||||
import ReverseEngineeringGui
|
||||
import ReverseEngineering
|
||||
|
||||
def GetClassName(self):
|
||||
return "ReverseEngineeringGui::Workbench"
|
||||
|
||||
|
||||
Gui.addWorkbench(ReverseEngineeringWorkbench())
|
||||
|
||||
@@ -29,19 +29,19 @@
|
||||
// Reen
|
||||
#ifndef ReenExport
|
||||
#ifdef ReverseEngineering_EXPORTS
|
||||
# define ReenExport FREECAD_DECL_EXPORT
|
||||
#define ReenExport FREECAD_DECL_EXPORT
|
||||
#else
|
||||
# define ReenExport FREECAD_DECL_IMPORT
|
||||
#define ReenExport FREECAD_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ReenGui
|
||||
#ifndef ReenGuiExport
|
||||
#ifdef ReverseEngineeringGui_EXPORTS
|
||||
# define ReenGuiExport FREECAD_DECL_EXPORT
|
||||
#define ReenGuiExport FREECAD_DECL_EXPORT
|
||||
#else
|
||||
# define ReenGuiExport FREECAD_DECL_IMPORT
|
||||
#define ReenGuiExport FREECAD_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif //REEN_GLOBAL_H
|
||||
#endif// REEN_GLOBAL_H
|
||||
|
||||
Reference in New Issue
Block a user