Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bfeba4a54 | |||
| 5d969f7d03 | |||
| 1e671d031f | |||
| 7be9995b77 | |||
| e3e91d6c3a | |||
| b2b3e4a2da | |||
| 2e6e698217 | |||
| e5117c0453 | |||
| 07d5b3a110 | |||
| a324ada5e6 | |||
| b2d4b175cc | |||
| b3a6fb7a29 | |||
| ee6175825e | |||
| e88169af12 |
@@ -31,7 +31,7 @@ bool
|
|||||||
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist)
|
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Il cilindro deve essere ben definito
|
// Il cilindro deve essere ben definito
|
||||||
if ( dR < EPS_SMALL || dH < EPS_SMALL)
|
if ( dR < EPS_SMALL || abs( dH) < EPS_SMALL)
|
||||||
return true ;
|
return true ;
|
||||||
// Se superficie non valida o aperta, non ha senso proseguire
|
// Se superficie non valida o aperta, non ha senso proseguire
|
||||||
if ( ! Stm.IsValid() || ! Stm.IsClosed())
|
if ( ! Stm.IsValid() || ! Stm.IsClosed())
|
||||||
@@ -81,7 +81,7 @@ bool
|
|||||||
TestCylSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist)
|
TestCylSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Il cilindro deve essere ben definito
|
// Il cilindro deve essere ben definito
|
||||||
if ( dR < EPS_SMALL || dH < EPS_SMALL)
|
if ( dR < EPS_SMALL || abs( dH) < EPS_SMALL)
|
||||||
return true ;
|
return true ;
|
||||||
// Se superficie non valida, non ha senso proseguire
|
// Se superficie non valida, non ha senso proseguire
|
||||||
if ( ! Stm.IsValid())
|
if ( ! Stm.IsValid())
|
||||||
|
|||||||
Binary file not shown.
+6
-2
@@ -201,6 +201,7 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
|||||||
int nClosure = bClosed ? 1 : 0 ;
|
int nClosure = bClosed ? 1 : 0 ;
|
||||||
bool bCheckingClosure = false ;
|
bool bCheckingClosure = false ;
|
||||||
bool bPlanarConcCvex = false ;
|
bool bPlanarConcCvex = false ;
|
||||||
|
bool bPrevTwoPointsWereConvex = false ;
|
||||||
for ( int i = 1 ; i <= pCrv->GetCurveCount() + nClosure ; ++i) {
|
for ( int i = 1 ; i <= pCrv->GetCurveCount() + nClosure ; ++i) {
|
||||||
int nCurr = i ;
|
int nCurr = i ;
|
||||||
int nPrev = i - 1 ;
|
int nPrev = i - 1 ;
|
||||||
@@ -224,7 +225,7 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
|||||||
// negli altri casi faccio la media
|
// negli altri casi faccio la media
|
||||||
if ( vFlag[nCurr] != OffsetCurve3d::AngType::ANG_CVEX)
|
if ( vFlag[nCurr] != OffsetCurve3d::AngType::ANG_CVEX)
|
||||||
vtTang = Media( vtDirCurr, vtDirPrev) ;
|
vtTang = Media( vtDirCurr, vtDirPrev) ;
|
||||||
else if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CVEX && vFlag[nPrev] != OffsetCurve3d::AngType::ANG_CVEX)
|
else if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CVEX && ( vFlag[nPrev] != OffsetCurve3d::AngType::ANG_CVEX || bPrevTwoPointsWereConvex))
|
||||||
vtTang = vtDirPrev ;
|
vtTang = vtDirPrev ;
|
||||||
else
|
else
|
||||||
vtTang = vtDirCurr ;
|
vtTang = vtDirCurr ;
|
||||||
@@ -244,7 +245,7 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
|||||||
dRadCorr = dOffDist ;
|
dRadCorr = dOffDist ;
|
||||||
ptP = ptP + dRadCorr * dCorrK * vtCorr ;
|
ptP = ptP + dRadCorr * dCorrK * vtCorr ;
|
||||||
// se secondo punto di angolo esterno di fianco, inserisco movimenti intermedi
|
// se secondo punto di angolo esterno di fianco, inserisco movimenti intermedi
|
||||||
if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CVEX && vFlag[nPrev] == OffsetCurve3d::AngType::ANG_CVEX && bPlanarConcCvex) {
|
if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CVEX && vFlag[nPrev] == OffsetCurve3d::AngType::ANG_CVEX && ! bPrevTwoPointsWereConvex && bPlanarConcCvex) {
|
||||||
double dAlfa = acos( vtTang * vtTangPrev) ;
|
double dAlfa = acos( vtTang * vtTangPrev) ;
|
||||||
double dDelta = dOffDist * tan( dAlfa / 4) ;
|
double dDelta = dOffDist * tan( dAlfa / 4) ;
|
||||||
Point3d ptAdd1 = ptPrev + dDelta * vtTangPrev ;
|
Point3d ptAdd1 = ptPrev + dDelta * vtTangPrev ;
|
||||||
@@ -256,7 +257,10 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
|||||||
pCL2->Set( ptAdd1, ptAdd2) ;
|
pCL2->Set( ptAdd1, ptAdd2) ;
|
||||||
vOffsetCrvs.emplace_back( pCL2, OffsetCurve3d::AngType::ANG_CVEX, -1) ;
|
vOffsetCrvs.emplace_back( pCL2, OffsetCurve3d::AngType::ANG_CVEX, -1) ;
|
||||||
ptPrev = ptAdd2 ;
|
ptPrev = ptAdd2 ;
|
||||||
|
bPrevTwoPointsWereConvex = true ;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
bPrevTwoPointsWereConvex = false ;
|
||||||
Vector3d vtAng = vtDirPrev ^ vtDirCurr ;
|
Vector3d vtAng = vtDirPrev ^ vtDirCurr ;
|
||||||
const double COS_ANG_MAX_PLANAR = 0.7 ;
|
const double COS_ANG_MAX_PLANAR = 0.7 ;
|
||||||
bPlanarConcCvex = false ;
|
bPlanarConcCvex = false ;
|
||||||
|
|||||||
+60
-1
@@ -2258,7 +2258,66 @@ GetSurfExtension( const ISurfTriMesh* pSrfTM, double dExtLen, int nLoop, int nSu
|
|||||||
SaveGeoObj( vGeo, vCol, "C:\\Temp\\curve offset 3d\\surfExtend_con-cvx.nge") ;
|
SaveGeoObj( vGeo, vCol, "C:\\Temp\\curve offset 3d\\surfExtend_con-cvx.nge") ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PtrOwner<ISurfTriMesh> pSurfExt( GetSurfTriMeshRuled( pEdge, pOffEdge, ISurfTriMesh::RuledType::RLT_MINDIST, dLinTol)) ;
|
PtrOwner<ISurfTriMesh> pSurfExt( GetSurfTriMeshRuled( pOffEdge, pEdge, ISurfTriMesh::RuledType::RLT_MINDIST, dLinTol)) ;
|
||||||
|
|
||||||
|
return Release( pSurfExt) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
GetSurfExtensionFromMany( const CISURFPVECTOR vpSurf, double dExtLen, const ICurve* pEdge, ICurve*& pOffEdge, int nType, double dLinTol)
|
||||||
|
{
|
||||||
|
// controlli sui parametri in input
|
||||||
|
if ( any_of( vpSurf.begin(), vpSurf.end(), []( const ISurf* pSurf){ return pSurf == nullptr ;}) || pEdge == nullptr)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
PNT5AXVECTOR vPnt5Ax ;
|
||||||
|
ProjectCurveOnSurf( *pEdge, vpSurf, dLinTol, 2.5, true, vPnt5Ax, false) ;
|
||||||
|
|
||||||
|
OffsetCurve3d off3d ;
|
||||||
|
if ( ! off3d.Make( vPnt5Ax, dExtLen, nType))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
PtrOwner<ICurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||||
|
for ( int i = 0 ; i < off3d.GetCurveCount() ; ++i) {
|
||||||
|
if ( ! pCC->AddCurve( off3d.GetLongerCurve()))
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
pOffEdge = Release( pCC) ;
|
||||||
|
|
||||||
|
#if SAVEEXTEND
|
||||||
|
vvGeo.clear() ;
|
||||||
|
vCol.clear() ;
|
||||||
|
vvGeo.emplace_back() ;
|
||||||
|
vvGeo.back().push_back( pEdge->Clone()) ;
|
||||||
|
vvGeo.back().push_back( pOffEdge->Clone()) ;
|
||||||
|
vCol.push_back( AQUA) ;
|
||||||
|
vvGeo.emplace_back() ;
|
||||||
|
for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) {
|
||||||
|
IGeoVector3d* pGV = CreateGeoVector3d() ;
|
||||||
|
pGV->Set( vPnt5Ax[i].vtDir1 * dExtLen, vPnt5Ax[i].ptP) ;
|
||||||
|
vvGeo.back().push_back( pGV) ;
|
||||||
|
}
|
||||||
|
vCol.push_back( LIME) ;
|
||||||
|
SaveGeoObj( vvGeo, vCol, "C:\\Temp\\curve offset 3d\\surfExtend_insight.nge") ;
|
||||||
|
|
||||||
|
vGeo.clear() ;
|
||||||
|
vCol.clear() ;
|
||||||
|
for ( int i = 1 ; i < ssize( vPnt5Ax) ; ++i) {
|
||||||
|
ICurveLine* pCL = CreateBasicCurveLine() ;
|
||||||
|
pCL->Set( vPnt5Ax[i-1].ptP, vPnt5Ax[i].ptP) ;
|
||||||
|
vGeo.push_back( pCL) ;
|
||||||
|
if ( vPnt5Ax[i].nFlag == 6)
|
||||||
|
vCol.push_back( GREEN) ;
|
||||||
|
else if ( vPnt5Ax[i].nFlag == 2)
|
||||||
|
vCol.push_back( RED) ;
|
||||||
|
else
|
||||||
|
vCol.push_back( PURPLE) ;
|
||||||
|
}
|
||||||
|
SaveGeoObj( vGeo, vCol, "C:\\Temp\\curve offset 3d\\surfExtend_con-cvx.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PtrOwner<ISurfTriMesh> pSurfExt( GetSurfTriMeshRuled( pOffEdge, pEdge, ISurfTriMesh::RuledType::RLT_MINDIST, dLinTol)) ;
|
||||||
|
|
||||||
return Release( pSurfExt) ;
|
return Release( pSurfExt) ;
|
||||||
}
|
}
|
||||||
+1
-1
@@ -6280,7 +6280,7 @@ ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
|||||||
double dU0 ; pSubEdge1->GetParamAtPoint( vSyncLines.end()[-2].first, dU0, TOL) ;
|
double dU0 ; pSubEdge1->GetParamAtPoint( vSyncLines.end()[-2].first, dU0, TOL) ;
|
||||||
double dU1 ; pSubEdge1->GetParamAtPoint( vSyncLines.end()[-1].first, dU1, TOL) ;
|
double dU1 ; pSubEdge1->GetParamAtPoint( vSyncLines.end()[-1].first, dU1, TOL) ;
|
||||||
if ( dU0 > dU1 - EPS_SMALL)
|
if ( dU0 > dU1 - EPS_SMALL)
|
||||||
swap( vSyncLines.end()[-2], vSyncLines[-1]) ;
|
swap( vSyncLines.end()[-2], vSyncLines.end()[-1]) ;
|
||||||
// Verifico che le curve non si intreccino
|
// Verifico che le curve non si intreccino
|
||||||
pSubEdge2->GetParamAtPoint( vSyncLines.end()[-2].second, dU0, TOL) ;
|
pSubEdge2->GetParamAtPoint( vSyncLines.end()[-2].second, dU0, TOL) ;
|
||||||
pSubEdge2->GetParamAtPoint( vSyncLines.end()[-1].second, dU1, TOL) ;
|
pSubEdge2->GetParamAtPoint( vSyncLines.end()[-1].second, dU1, TOL) ;
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
|||||||
bool AddExtLoop( ICurve* pCrv) override ;
|
bool AddExtLoop( ICurve* pCrv) override ;
|
||||||
bool AddIntLoop( const ICurve& cCrv) override ;
|
bool AddIntLoop( const ICurve& cCrv) override ;
|
||||||
bool AddIntLoop( ICurve* pCrv) override ;
|
bool AddIntLoop( ICurve* pCrv) override ;
|
||||||
|
bool Cut( const Plane3d& plPlane) override ;
|
||||||
bool Add( const ISurfFlatRegion& Other) override ;
|
bool Add( const ISurfFlatRegion& Other) override ;
|
||||||
bool Subtract( const ISurfFlatRegion& Other) override ;
|
bool Subtract( const ISurfFlatRegion& Other) override ;
|
||||||
bool Intersect( const ISurfFlatRegion& Other) override ;
|
bool Intersect( const ISurfFlatRegion& Other) override ;
|
||||||
|
|||||||
@@ -21,13 +21,99 @@
|
|||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|
||||||
#define SAVELOOPS 0
|
#define SAVELOOPS 0
|
||||||
#if SAVELOOPS
|
#define DEBUG_PLANE_CUT 0
|
||||||
std::vector<IGeoObj*> vGeo ;
|
#if SAVELOOPS || DEBUG_PLANE_CUT
|
||||||
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||||
|
#include "/EgtDev/Include/EGkColor.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoVector3d.h"
|
||||||
|
#include "CurveArc.h"
|
||||||
|
std::vector<IGeoObj*> vGeo ;
|
||||||
|
std::vector<Color> vCol ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfFlatRegion::Cut( const Plane3d& plPlane)
|
||||||
|
{
|
||||||
|
// verifico che la superficie corrente e il piano di taglio siano validi
|
||||||
|
if ( ! IsValid() || ! plPlane.IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// !<-- Il taglio avviene nel verso della normale
|
||||||
|
|
||||||
|
// recupero le normali del piano e della superficie
|
||||||
|
const Vector3d vtPlane = plPlane.GetVersN() ;
|
||||||
|
const Vector3d vtN = GetNormVersor() ;
|
||||||
|
// recupero il centroide e la distanza tra esso e il piano
|
||||||
|
Point3d ptCentroid ; GetCentroid( ptCentroid) ;
|
||||||
|
double dDist = DistPointPlane( ptCentroid, plPlane) ;
|
||||||
|
|
||||||
|
#if DEBUG_PLANE_CUT
|
||||||
|
vGeo.clear() ; vCol.clear() ;
|
||||||
|
CurveArc crvPlane ; crvPlane.Set( plPlane.GetPoint(), plPlane.GetVersN(), 1e5) ;
|
||||||
|
SurfFlatRegion sfrPlane ; sfrPlane.AddExtLoop( crvPlane) ;
|
||||||
|
vGeo.emplace_back( sfrPlane.Clone()) ; vCol.emplace_back( BLUE) ;
|
||||||
|
vGeo.push_back( this->Clone()) ; vCol.emplace_back( LIME) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- se le normali sono tra di loro parallele
|
||||||
|
if ( AreSameOrOppositeVectorApprox( vtPlane, vtN)) {
|
||||||
|
// la normale della superficie non ha importanza, basta solo verificare se la superficie si trova sopra, sotto o nel piano
|
||||||
|
// --- se la superficie giace nel piano, allora la svuoto
|
||||||
|
if ( abs( dDist) < EPS_SMALL)
|
||||||
|
Clear() ;
|
||||||
|
// --- se la superficie si trova sopra al piano, allora la svuoto
|
||||||
|
else if ( dDist > 0.)
|
||||||
|
Clear() ;
|
||||||
|
// --- se la superficie si trova sotto allora non devo fare nulla
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- essendo la superficie e il piano non paralleli, mettendomi nel sistema di riferimento della superficie posso considerare il
|
||||||
|
// piano come una linea e classificare i Loop in base al Side. Tutto ciò che si trova nel Side Left viene trimmato
|
||||||
|
Vector3d vtLineDir = vtPlane ^ vtN ;
|
||||||
|
double dSqSin = vtLineDir.SqLen() ;
|
||||||
|
if ( dSqSin < SQ_EPS_SMALL)
|
||||||
|
return false ;
|
||||||
|
Vector3d vtNProj = OrthoCompo( vtPlane, vtN) ;
|
||||||
|
Point3d ptLine = ptCentroid + vtNProj * ( - dDist / dSqSin) ; // !<-- dDist è negativa
|
||||||
|
if ( ! vtLineDir.Normalize())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// definisco la linea di classificazione ( interna al frame della superficie)
|
||||||
|
BBox3d BBox2d ;
|
||||||
|
if ( ! GetLocalBBox( BBox2d))
|
||||||
|
return false ;
|
||||||
|
double dBoxDiam ; BBox2d.GetDiameter( dBoxDiam) ;
|
||||||
|
const double dDepth = Dist( ptLine, ptCentroid) + 2. * dBoxDiam ;
|
||||||
|
Point3d ptLineS = ptLine - dDepth * vtLineDir ;
|
||||||
|
Point3d ptLineE = ptLine + dDepth * vtLineDir ;
|
||||||
|
|
||||||
|
// definisco la regione di influenza del piano
|
||||||
|
CurveComposite CompoRect ;
|
||||||
|
CompoRect.AddPoint( ptLineS) ;
|
||||||
|
CompoRect.AddLine( ptLineS + GetRotate( vtLineDir, m_frF.VersZ(), ANG_RIGHT) * dDepth) ;
|
||||||
|
CompoRect.AddLine( ptLineE + GetRotate( vtLineDir, m_frF.VersZ(), ANG_RIGHT) * dDepth) ;
|
||||||
|
CompoRect.AddLine( ptLineE) ;
|
||||||
|
CompoRect.Close() ;
|
||||||
|
SurfFlatRegion SfrRect ;
|
||||||
|
if ( ! SfrRect.AddExtLoop( CompoRect))
|
||||||
|
return false ;
|
||||||
|
if ( AreOppositeVectorApprox( SfrRect.GetNormVersor(), m_frF.VersZ()))
|
||||||
|
SfrRect.Invert() ;
|
||||||
|
|
||||||
|
#if DEBUG_PLANE_CUT
|
||||||
|
vGeo.push_back( SfrRect.Clone()) ; vCol.emplace_back( RED) ;
|
||||||
|
SaveGeoObj( vGeo, vCol, "C:\\Temp\\SfrPlaneCut.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Classifico le curve della regione
|
||||||
|
return ( Subtract( SfrRect)) ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfFlatRegion::Add( const ISurfFlatRegion& Other)
|
SurfFlatRegion::Add( const ISurfFlatRegion& Other)
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ struct IntersToCheck {
|
|||||||
|
|
||||||
typedef std::vector<IntersToCheck> INTTOCHECKVEC ;
|
typedef std::vector<IntersToCheck> INTTOCHECKVEC ;
|
||||||
|
|
||||||
|
struct Neigh { // 6 7 8
|
||||||
|
double nI ; // 3 s 5
|
||||||
|
double nJ ; // 0 1 2
|
||||||
|
int nN ; // n-esimo vicino di uno spillone : numerati così
|
||||||
|
Neigh( double _nI, double _nJ, int _nN) : nI( _nI), nJ( _nJ), nN( _nN) { ;}
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class VolZmap : public IVolZmap, public IGeoObjRW
|
class VolZmap : public IVolZmap, public IGeoObjRW
|
||||||
{
|
{
|
||||||
@@ -483,7 +490,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||||
bool AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHECKVEC& vIntToCheck, const Point3d& ptMapOrig,
|
bool AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHECKVEC& vIntToCheck, const Point3d& ptMapOrig,
|
||||||
const ISurfTriMesh& Surf, const IntersParLinesSurfTm& intPLSTM) ;
|
const ISurfTriMesh& Surf, const IntersParLinesSurfTm& intPLSTM) ;
|
||||||
DBLDBLVECTOR GetNeighbours( int nG, int nI, int nJ, double dPar) ;
|
bool SearchMissingIntervals( int nMap, INTTOCHECKVEC& vIntToCheck) ;
|
||||||
|
std::vector<Neigh> GetNeighbours( int nG, int nI, int nJ, double dPar) ;
|
||||||
// Funzioni per Offset di superfici
|
// Funzioni per Offset di superfici
|
||||||
bool InitVolZMapOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
|
bool InitVolZMapOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
|
||||||
bool InitVolZMapThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
|
bool InitVolZMapThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
|
||||||
|
|||||||
+429
-150
@@ -22,6 +22,7 @@
|
|||||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
#include <future>
|
#include <future>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -606,8 +607,10 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
|
|||||||
if ( k > 0) {
|
if ( k > 0) {
|
||||||
int z = k - 1 ;
|
int z = k - 1 ;
|
||||||
// controllo se l'intersezione corrente è coincidente con la precedente, per esempio se ILTT == 4 ( intersezione su un lato di un triangolo, quindi con 2 triangoli)
|
// controllo se l'intersezione corrente è coincidente con la precedente, per esempio se ILTT == 4 ( intersezione su un lato di un triangolo, quindi con 2 triangoli)
|
||||||
|
// controllo anche che le proiezioni delle normali abbiano lo stesso segno rispetto allo spillone
|
||||||
if ( IntersectionResults[k].dU - IntersectionResults[z].dU < EPS_SMALL &&
|
if ( IntersectionResults[k].dU - IntersectionResults[z].dU < EPS_SMALL &&
|
||||||
IntersectionResults[k].dCosDN - IntersectionResults[z].dCosDN < EPS_SMALL)
|
IntersectionResults[k].dCosDN - IntersectionResults[z].dCosDN < EPS_SMALL &&
|
||||||
|
IntersectionResults[k].dCosDN * IntersectionResults[z].dCosDN > 0)
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,6 +637,10 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
|
|||||||
Surf.GetFacetNormal( nF, vtInN) ;
|
Surf.GetFacetNormal( nF, vtInN) ;
|
||||||
|
|
||||||
bInside = true ;
|
bInside = true ;
|
||||||
|
if ( k == nInt - 1) {
|
||||||
|
// se ho un ingresso ma è l'ultima intersezione vuol dire che è spaiata
|
||||||
|
vIntToCheck.emplace_back( IntersectionResults[k].ptI, vtInN, IntersectionResults[k].dU, nMap, i, j) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// esco dalla superficie trimesh
|
// esco dalla superficie trimesh
|
||||||
@@ -677,6 +684,10 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
|
|||||||
if ( bForceClosed) {
|
if ( bForceClosed) {
|
||||||
if ( ! AdjustDexelThroughCracks( nMap, vtLen, vIntToCheck, ptMapOrig, Surf, intPLSTM))
|
if ( ! AdjustDexelThroughCracks( nMap, vtLen, vIntToCheck, ptMapOrig, Surf, intPLSTM))
|
||||||
return false ;
|
return false ;
|
||||||
|
vIntToCheck.clear() ;
|
||||||
|
SearchMissingIntervals( nMap, vIntToCheck) ;
|
||||||
|
if ( ! AdjustDexelThroughCracks( nMap, vtLen, vIntToCheck, ptMapOrig, Surf, intPLSTM))
|
||||||
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@@ -979,7 +990,7 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
|
|||||||
IntersParLinesSurfTm intPLSTM( frMapFrame, Surf) ;
|
IntersParLinesSurfTm intPLSTM( frMapFrame, Surf) ;
|
||||||
|
|
||||||
// Standarda è multithread
|
// Standarda è multithread
|
||||||
constexpr bool MULTITHREAD = false ;
|
constexpr bool MULTITHREAD = true ;
|
||||||
if ( MULTITHREAD) {
|
if ( MULTITHREAD) {
|
||||||
|
|
||||||
// Numero massimo di thread
|
// Numero massimo di thread
|
||||||
@@ -1048,30 +1059,30 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
|
|||||||
return bCompleted ;
|
return bCompleted ;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBLDBLVECTOR
|
vector<Neigh>
|
||||||
VolZmap::GetNeighbours( int nG, int nI, int nJ, double dPar)
|
VolZmap::GetNeighbours( int nG, int nI, int nJ, double dPar)
|
||||||
{
|
{
|
||||||
DBLDBLVECTOR vNeigh ;
|
vector<Neigh> vNeigh ;
|
||||||
// parto da in basso a sinistra e procedo per righe, saltando il punto corrente
|
// parto da in basso a sinistra e procedo per righe, saltando il punto corrente
|
||||||
if ( nI > 0 && nJ > 0)
|
if ( nI > 0 && nJ > 0)
|
||||||
vNeigh.emplace_back( nI - dPar, nJ - dPar) ;
|
vNeigh.emplace_back( nI - dPar, nJ - dPar, 0) ;
|
||||||
if ( nJ > 0) {
|
if ( nJ > 0) {
|
||||||
vNeigh.emplace_back( nI, nJ - dPar) ;
|
vNeigh.emplace_back( nI, nJ - dPar, 1) ;
|
||||||
if ( nI < m_nNx[nG] - dPar)
|
if ( nI < m_nNx[nG] - dPar)
|
||||||
vNeigh.emplace_back( nI + dPar, nJ - dPar) ;
|
vNeigh.emplace_back( nI + dPar, nJ - dPar, 2) ;
|
||||||
}
|
}
|
||||||
// passo alla fila contenente il punto corrente
|
// passo alla fila contenente il punto corrente
|
||||||
if ( nI > 0)
|
if ( nI > 0)
|
||||||
vNeigh.emplace_back( nI - dPar, nJ) ;
|
vNeigh.emplace_back( nI - dPar, nJ, 3) ;
|
||||||
if ( nI < m_nNx[nG] - dPar)
|
if ( nI < m_nNx[nG] - dPar)
|
||||||
vNeigh.emplace_back( nI + dPar, nJ) ;
|
vNeigh.emplace_back( nI + dPar, nJ, 5) ;
|
||||||
// passo alla fila successiva a quella del corrente
|
// passo alla fila successiva a quella del corrente
|
||||||
if ( nJ < m_nNy[nG] - dPar) {
|
if ( nJ < m_nNy[nG] - dPar) {
|
||||||
if ( nI > 0)
|
if ( nI > 0)
|
||||||
vNeigh.emplace_back( nI - dPar, nJ + dPar) ;
|
vNeigh.emplace_back( nI - dPar, nJ + dPar, 6) ;
|
||||||
vNeigh.emplace_back( nI, nJ + dPar) ;
|
vNeigh.emplace_back( nI, nJ + dPar, 7) ;
|
||||||
if ( nI < m_nNx[nG])
|
if ( nI < m_nNx[nG] - dPar)
|
||||||
vNeigh.emplace_back( nI + dPar, nJ + dPar) ;
|
vNeigh.emplace_back( nI + dPar, nJ + dPar, 8) ;
|
||||||
}
|
}
|
||||||
return vNeigh ;
|
return vNeigh ;
|
||||||
}
|
}
|
||||||
@@ -1083,6 +1094,7 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE
|
|||||||
{
|
{
|
||||||
double dAngSameFace = 45 ;
|
double dAngSameFace = 45 ;
|
||||||
double dCosSmall = sin( EPS_ANG_SMALL * DEGTORAD) ;
|
double dCosSmall = sin( EPS_ANG_SMALL * DEGTORAD) ;
|
||||||
|
double dMaxDistTol = 3 * m_dStep ;
|
||||||
// per ogni intersezione segnalata devo cercare sugli spilloni vicini l'intervallo con l'estremo più vicino a questa intersezione
|
// per ogni intersezione segnalata devo cercare sugli spilloni vicini l'intervallo con l'estremo più vicino a questa intersezione
|
||||||
// e usare l'altro estremo, insieme a quello degli altri spilloni vicini, per estrapolare quello mancante sullo spillone corrente
|
// e usare l'altro estremo, insieme a quello degli altri spilloni vicini, per estrapolare quello mancante sullo spillone corrente
|
||||||
Vector3d vtAx ;
|
Vector3d vtAx ;
|
||||||
@@ -1094,104 +1106,112 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE
|
|||||||
vtAx = Y_AX ;
|
vtAx = Y_AX ;
|
||||||
for ( const auto& itc : vIntToCheck) {
|
for ( const auto& itc : vIntToCheck) {
|
||||||
int nPos = itc.nJ * m_nNx[nG] + itc.nI ;
|
int nPos = itc.nJ * m_nNx[nG] + itc.nI ;
|
||||||
double dPosRef = itc.ptInters.v[( nG + 2) % 3] ;
|
double dPosRef = itc.dU ;
|
||||||
// controllo se esiste già un intervallo con un estremo quasi coincidente a quello segnalato
|
bool bUseNeighInfo = true ;
|
||||||
// ed entrambi sono entrate o uscite
|
// se il punto di intersezione passato non è valido vuol dire che non ho neanche un'intersezione spaiata da cui partire a cercare
|
||||||
bool bNeedToReconstruct = true ;
|
bool bHaveRef = true ;
|
||||||
for ( const auto& data: m_Values[nG][nPos]) {
|
if ( ! isfinite( dPosRef)) {
|
||||||
if ( (( abs( dPosRef - data.dMin) < 10 * EPS_SMALL && ( itc.vtN * vtAx) * ( data.vtMinN * vtAx) > 0)) ||
|
bHaveRef = false ;
|
||||||
(( abs( dPosRef - data.dMax) < 10 * EPS_SMALL && ( itc.vtN * vtAx) * ( data.vtMaxN * vtAx) > 0))) {
|
bUseNeighInfo = false ;
|
||||||
bNeedToReconstruct = false ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ( ! bNeedToReconstruct)
|
|
||||||
continue ;
|
|
||||||
DBLDBLVECTOR vNeigh = GetNeighbours( nG, itc.nI, itc.nJ, m_dStep) ;
|
|
||||||
PNTVECTOR vNeighInters ;
|
PNTVECTOR vNeighInters ;
|
||||||
Vector3d vtMeanN = V_NULL ;
|
Vector3d vtMeanN = V_NULL ;
|
||||||
bool bSearchingInOrOut = itc.vtN * vtAx > 0 ;
|
if ( bHaveRef) {
|
||||||
bool bUseNeighInfo = true ;
|
// controllo se esiste già un intervallo con un estremo quasi coincidente a quello segnalato
|
||||||
for ( const auto& [i,j] : vNeigh) {
|
// ed entrambi sono entrate o uscite
|
||||||
double dMinDist = INFINITO ;
|
bool bNeedToReconstruct = true ;
|
||||||
double dCorrespInters = INFINITO ;
|
|
||||||
double dNearestPos = NAN ;
|
|
||||||
Vector3d vtNearestN ;
|
|
||||||
int nNeighPos = int( j) * m_nNx[nG] + int( i) ;
|
|
||||||
for ( const auto& data: m_Values[nG][nNeighPos]) {
|
|
||||||
double dDist1 = abs( dPosRef - data.dMin) ;
|
|
||||||
double dDist2 = abs( dPosRef - data.dMax) ;
|
|
||||||
if ( dDist1 < dMinDist || dDist2 < dMinDist) {
|
|
||||||
dMinDist = min( dDist1, dDist2) ;
|
|
||||||
|
|
||||||
// se sto cercando un ingresso
|
|
||||||
if ( bSearchingInOrOut) {
|
|
||||||
if ( data.vtMaxN * vtAx < 0) {
|
|
||||||
dNearestPos = data.dMax ;
|
|
||||||
vtNearestN = data.vtMaxN ;
|
|
||||||
dCorrespInters = data.dMin ;
|
|
||||||
}
|
|
||||||
else if ( data.vtMinN * vtAx < 0) {
|
|
||||||
dNearestPos = data.dMin ;
|
|
||||||
vtNearestN = data.vtMinN ;
|
|
||||||
dCorrespInters = data.dMax ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se sto cercando un'uscita
|
|
||||||
else {
|
|
||||||
if ( data.vtMaxN * vtAx > 0) {
|
|
||||||
dNearestPos = data.dMax ;
|
|
||||||
vtNearestN = data.vtMaxN ;
|
|
||||||
dCorrespInters = data.dMin ;
|
|
||||||
}
|
|
||||||
else if ( data.vtMinN * vtAx > 0) {
|
|
||||||
dNearestPos = data.dMin ;
|
|
||||||
vtNearestN = data.vtMinN ;
|
|
||||||
dCorrespInters = data.dMax ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// verifico che il dNearestPos sia effettivamente associato al tratto che sto cercando di ricostruire
|
|
||||||
// e non ad un altro presente sullo spillone corrente
|
|
||||||
bool bAddNearest = true ;
|
|
||||||
for ( const auto& data: m_Values[nG][nPos]) {
|
for ( const auto& data: m_Values[nG][nPos]) {
|
||||||
double dDist1 = abs( dCorrespInters - data.dMin) ;
|
if ( (( abs( dPosRef - data.dMin) < 10 * EPS_SMALL && ( itc.vtN * vtAx) * ( data.vtMinN * vtAx) > 0)) ||
|
||||||
double dDist2 = abs( dCorrespInters - data.dMax) ;
|
(( abs( dPosRef - data.dMax) < 10 * EPS_SMALL && ( itc.vtN * vtAx) * ( data.vtMaxN * vtAx) > 0))) {
|
||||||
if ( dDist1 < dMinDist || dDist2 < dMinDist) {
|
bNeedToReconstruct = false ;
|
||||||
bAddNearest = false ;
|
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( ! bNeedToReconstruct)
|
||||||
|
continue ;
|
||||||
|
vector<Neigh> vNeigh = GetNeighbours( nG, itc.nI, itc.nJ, 1) ;
|
||||||
|
bool bSearchingInOrOut = itc.vtN * vtAx > 0 ;
|
||||||
|
for ( const auto& [i, j, n] : vNeigh) {
|
||||||
|
double dMinDist = INFINITO ;
|
||||||
|
double dCorrespInters = INFINITO ;
|
||||||
|
double dNearestPos = NAN ;
|
||||||
|
Vector3d vtNearestN ;
|
||||||
|
int nNeighPos = int( j) * m_nNx[nG] + int( i) ;
|
||||||
|
for ( const auto& data : m_Values[nG][nNeighPos]) {
|
||||||
|
double dDist1 = abs( dPosRef - data.dMin) ;
|
||||||
|
double dDist2 = abs( dPosRef - data.dMax) ;
|
||||||
|
if ( dDist1 < dMinDist || dDist2 < dMinDist) {
|
||||||
|
dMinDist = min( dDist1, dDist2) ;
|
||||||
|
|
||||||
if ( bAddNearest && isfinite( dNearestPos)) {
|
// se sto cercando un ingresso
|
||||||
// controllo anche che i punti non siano troppo lontani tra loro, altrimenti
|
if ( bSearchingInOrOut) {
|
||||||
// il piano calcolato potrebbe essere una media troppo grezza
|
if ( data.vtMaxN * vtAx < 0) {
|
||||||
double dMaxDist = 3 * m_dStep ;
|
dNearestPos = data.dMax ;
|
||||||
const bool bTooFar = any_of( vNeighInters.begin(), vNeighInters.end(),
|
vtNearestN = data.vtMaxN ;
|
||||||
[ dNearestPos, dMaxDist]( const Point3d& pt) {
|
dCorrespInters = data.dMin ;
|
||||||
return abs( pt.z - dNearestPos) > dMaxDist ;
|
}
|
||||||
}) ;
|
else if ( data.vtMinN * vtAx < 0) {
|
||||||
double dAng ;
|
dNearestPos = data.dMin ;
|
||||||
if ( ! bTooFar) {
|
vtNearestN = data.vtMinN ;
|
||||||
// controllo anche che gli angoli delle normali non cambino troppo
|
dCorrespInters = data.dMax ;
|
||||||
// calcolo l'angolo con la media delle precedenti perché il valore oltre cui
|
}
|
||||||
// considero le normali diverse è grande
|
}
|
||||||
vtNearestN.GetAngle( vtMeanN, dAng) ;
|
// se sto cercando un'uscita
|
||||||
|
else {
|
||||||
|
if ( data.vtMaxN * vtAx > 0) {
|
||||||
|
dNearestPos = data.dMax ;
|
||||||
|
vtNearestN = data.vtMaxN ;
|
||||||
|
dCorrespInters = data.dMin ;
|
||||||
|
}
|
||||||
|
else if ( data.vtMinN * vtAx > 0) {
|
||||||
|
dNearestPos = data.dMin ;
|
||||||
|
vtNearestN = data.vtMinN ;
|
||||||
|
dCorrespInters = data.dMax ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bAddNearest = ! bTooFar && dAng < dAngSameFace ;
|
// verifico che il dNearestPos sia effettivamente associato al tratto che sto cercando di ricostruire
|
||||||
if ( bAddNearest) {
|
// e non ad un altro presente sullo spillone corrente
|
||||||
double dX = ( i + 0.5) * m_dStep ;
|
bool bAddNearest = true ;
|
||||||
double dY = ( j + 0.5) * m_dStep ;
|
for ( const auto& data : m_Values[nG][nPos]) {
|
||||||
vNeighInters.emplace_back( dX, dY, dNearestPos) ;
|
double dDist1 = abs( dCorrespInters - data.dMin) ;
|
||||||
vtMeanN += vtNearestN ;
|
double dDist2 = abs( dCorrespInters - data.dMax) ;
|
||||||
|
if ( dDist1 < dMinDist || dDist2 < dMinDist) {
|
||||||
|
bAddNearest = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
if ( bAddNearest && isfinite( dNearestPos)) {
|
||||||
bUseNeighInfo = false ;
|
// controllo anche che i punti non siano troppo lontani tra loro, altrimenti
|
||||||
break ;
|
// il piano calcolato potrebbe essere una media troppo grezza
|
||||||
|
const bool bTooFar = any_of( vNeighInters.begin(), vNeighInters.end(),
|
||||||
|
[dNearestPos, dMaxDistTol](const Point3d& pt) {
|
||||||
|
return abs( pt.z - dNearestPos) > dMaxDistTol ;
|
||||||
|
}) ;
|
||||||
|
double dAng ;
|
||||||
|
if ( ! bTooFar) {
|
||||||
|
// controllo anche che gli angoli delle normali non cambino troppo
|
||||||
|
// calcolo l'angolo con la media delle precedenti perché il valore oltre cui
|
||||||
|
// considero le normali diverse è grande
|
||||||
|
vtNearestN.GetAngle( vtMeanN, dAng) ;
|
||||||
|
}
|
||||||
|
bAddNearest = ! bTooFar && dAng < dAngSameFace ;
|
||||||
|
if ( bAddNearest) {
|
||||||
|
double dX = ( i + 0.5) * m_dStep ;
|
||||||
|
double dY = ( j + 0.5) * m_dStep ;
|
||||||
|
vNeighInters.emplace_back( dX, dY, dNearestPos) ;
|
||||||
|
vtMeanN += vtNearestN ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bUseNeighInfo = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vector<Data> vNewIntervals ;
|
||||||
|
bool bAddAllIntervals = false ;
|
||||||
Point3d ptInt ;
|
Point3d ptInt ;
|
||||||
// se riesco uso i vicini per calcolare l'intersezione mancante
|
// se riesco uso i vicini per calcolare l'intersezione mancante
|
||||||
if ( bUseNeighInfo) {
|
if ( bUseNeighInfo) {
|
||||||
@@ -1214,16 +1234,25 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE
|
|||||||
Point3d ptKnown = itc.ptInters ;
|
Point3d ptKnown = itc.ptInters ;
|
||||||
Frame3d frGrid ;
|
Frame3d frGrid ;
|
||||||
if ( nG == 0)
|
if ( nG == 0)
|
||||||
frGrid.Set( ORIG, Frame3d::TOP) ;
|
frGrid.Set( ptMapOrig, Frame3d::TOP) ;
|
||||||
else if ( nG == 1)
|
else if ( nG == 1)
|
||||||
frGrid.Set( ORIG, Frame3d::RIGHT) ;
|
frGrid.Set( ptMapOrig, Frame3d::RIGHT) ;
|
||||||
else if ( nG == 2)
|
else if ( nG == 2)
|
||||||
frGrid.Set( ORIG, Z_AX, X_AX, Y_AX) ;
|
frGrid.Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
|
||||||
ptKnown.ToLoc( frGrid) ;
|
ptKnown.ToLoc( frGrid) ;
|
||||||
IntersLinePlane( ptKnown, Z_AX, INFINITO, plLoc, ptInt, false) ;
|
IntersLinePlane( ptKnown, Z_AX, INFINITO, plLoc, ptInt, false) ;
|
||||||
}
|
}
|
||||||
// altrimenti sposto di poco lo spillone e ricalcolo le intersezioni con la superficie, finché trovo l'intersezione mancante
|
// altrimenti sposto di poco lo spillone e ricalcolo le intersezioni con la superficie, finché trovo l'intersezione mancante
|
||||||
else {
|
else {
|
||||||
|
// controllo quanti intervalli hanno i vicini
|
||||||
|
vector<Neigh> vNeigh = GetNeighbours( nG, itc.nI, itc.nJ, 1) ;
|
||||||
|
int nMinIntervals = 0 ;
|
||||||
|
for ( const auto& [i, j, n] : vNeigh) {
|
||||||
|
int nNeighPos = int( j) * m_nNx[nG] + int( i) ;
|
||||||
|
if ( ssize(m_Values[nG][nNeighPos]) > nMinIntervals)
|
||||||
|
nMinIntervals = ssize(m_Values[nG][nNeighPos]) ;
|
||||||
|
}
|
||||||
|
|
||||||
bool bFound = false ;
|
bool bFound = false ;
|
||||||
DBLVECTOR vSmallStep ;
|
DBLVECTOR vSmallStep ;
|
||||||
vSmallStep.push_back( Clamp( 0.05 * m_dStep, 50 * EPS_SMALL, 1.)) ;
|
vSmallStep.push_back( Clamp( 0.05 * m_dStep, 50 * EPS_SMALL, 1.)) ;
|
||||||
@@ -1233,15 +1262,16 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE
|
|||||||
// se ciclando la raggiera non trovo un'intersezione valida allora potrei essermi spostato troppo poco dallo spillone originale e essere caduto ancora nella fessura
|
// se ciclando la raggiera non trovo un'intersezione valida allora potrei essermi spostato troppo poco dallo spillone originale e essere caduto ancora nella fessura
|
||||||
// quindi ciclo nuovamente aumentando un poco la distanza dallo spillone originale ( comunque sempre meno della distanza m_dStep)
|
// quindi ciclo nuovamente aumentando un poco la distanza dallo spillone originale ( comunque sempre meno della distanza m_dStep)
|
||||||
for ( int c = 0 ; c < ssize( vSmallStep) ; ++c) {
|
for ( int c = 0 ; c < ssize( vSmallStep) ; ++c) {
|
||||||
DBLDBLVECTOR vSmallMoveNeigh = GetNeighbours( nG, itc.nI, itc.nJ, vSmallStep[c]) ;
|
vector<Neigh> vSmallMoveNeigh = GetNeighbours( nG, itc.nI, itc.nJ, vSmallStep[c]) ;
|
||||||
for ( int n = 0 ; n < 8 ; ++n) {
|
for ( int n = 0 ; n < ssize( vSmallMoveNeigh) ; ++n) {
|
||||||
double dX = ( vSmallMoveNeigh[n].first + 0.5) * m_dStep ;
|
double dX = ( vSmallMoveNeigh[n].nI + 0.5) * m_dStep ;
|
||||||
double dY = ( vSmallMoveNeigh[n].second + 0.5) * m_dStep ;
|
double dY = ( vSmallMoveNeigh[n].nJ + 0.5) * m_dStep ;
|
||||||
Point3d ptP0( dX, dY, 0) ;
|
Point3d ptP0( dX, dY, 0) ;
|
||||||
ILSIVECTOR IntersectionResults ;
|
ILSIVECTOR IntersectionResults ;
|
||||||
intPLSTM.GetInters( ptP0, vtLen.v[(nG+2)%3], IntersectionResults) ;
|
intPLSTM.GetInters( ptP0, vtLen.v[(nG+2)%3], IntersectionResults) ;
|
||||||
// intervalli dalle intersezioni
|
// intervalli dalle intersezioni
|
||||||
vector<Data> vNewIntervals ;
|
vNewIntervals.clear() ;
|
||||||
|
DBLVECTOR vDiscardedInters ;
|
||||||
bool bInside = false ;
|
bool bInside = false ;
|
||||||
Vector3d vtInN ;
|
Vector3d vtInN ;
|
||||||
Point3d ptIn ;
|
Point3d ptIn ;
|
||||||
@@ -1258,6 +1288,10 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE
|
|||||||
double dCos = IntersectionResults[i].dCosDN ;
|
double dCos = IntersectionResults[i].dCosDN ;
|
||||||
// entro nella superficie trimesh
|
// entro nella superficie trimesh
|
||||||
if ( dCos < - dCosSmall) {
|
if ( dCos < - dCosSmall) {
|
||||||
|
if ( bInside) {
|
||||||
|
int k = i - 1 ;
|
||||||
|
vDiscardedInters.push_back( IntersectionResults[k].dU) ;
|
||||||
|
}
|
||||||
ptIn = IntersectionResults[i].ptI ;
|
ptIn = IntersectionResults[i].ptI ;
|
||||||
|
|
||||||
int nT = IntersectionResults[i].nT ;
|
int nT = IntersectionResults[i].nT ;
|
||||||
@@ -1269,7 +1303,11 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE
|
|||||||
}
|
}
|
||||||
|
|
||||||
// esco dalla superficie trimesh
|
// esco dalla superficie trimesh
|
||||||
else if ( dCos > dCosSmall && bInside) {
|
else if ( dCos > dCosSmall) {
|
||||||
|
if ( ! bInside) {
|
||||||
|
vDiscardedInters.push_back( IntersectionResults[i].dU) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
Point3d ptOut = IntersectionResults[i].ptI ;
|
Point3d ptOut = IntersectionResults[i].ptI ;
|
||||||
|
|
||||||
int nT = IntersectionResults[i].nT ;
|
int nT = IntersectionResults[i].nT ;
|
||||||
@@ -1294,23 +1332,137 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// controllo che abbia un intervallo in più rispetto a quelli di prima
|
//// controllo che abbia almeno un intervallo in più rispetto a quelli di prima
|
||||||
if ( ssize( vNewIntervals) == ssize( m_Values[nG][nPos]) + 1) {
|
//bool bValidNewIntrerval = ssize( vNewIntervals) > ssize( m_Values[nG][nPos]) ;
|
||||||
// dovrei verificare che quello in più sia effettivamente quello ricercato????
|
//if ( ! bHaveRef)
|
||||||
double dMinDist = INFINITO ;
|
// bValidNewIntrerval = bValidNewIntrerval && ssize( vNewIntervals) >= nMinIntervals ;
|
||||||
for ( const auto& data : vNewIntervals) {
|
|
||||||
if ( abs( data.dMin - dPosRef) < dMinDist) {
|
//// controllo che ci sia almeno un intervallo che non matcha con quelli già presenti
|
||||||
dMinDist = abs( data.dMin - dPosRef) ;
|
//bool bValidNewIntrerval = false ;
|
||||||
ptInt.Set( itc.nI + 0.5, itc.nJ + 0.5, data.dMax) ;
|
//if ( ssize( m_Values[nG][nPos]) == 0)
|
||||||
vtMeanN = data.vtMaxN ;
|
// bValidNewIntrerval = true ;
|
||||||
bFound = true ;
|
//else {
|
||||||
|
// for ( auto& dataCurr : m_Values[nG][nPos]) {
|
||||||
|
// // se ho una sovrapposizione tra intervalli ho una corrispondenza
|
||||||
|
// bool bMatch = false ;
|
||||||
|
// for ( auto& dataNew : vNewIntervals) {
|
||||||
|
// if ( dataCurr.dMin < dataNew.dMax && dataNew.dMin < dataCurr.dMax) {
|
||||||
|
// bMatch = true ;
|
||||||
|
// break ;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if ( ! bMatch) {
|
||||||
|
// bValidNewIntrerval = true ;
|
||||||
|
// break ;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
bool bValidNewInterval = false ;
|
||||||
|
// cerco se ho delle corrispondenza tra gli intervalli che avevo già sul corrente
|
||||||
|
// e quelli che ho trovato ora
|
||||||
|
bool bSplit = false ;
|
||||||
|
INTINTVECTOR vMatch ;
|
||||||
|
int nNew = 0 ;
|
||||||
|
for ( auto& dataNew : vNewIntervals) {
|
||||||
|
// se ho una sovrapposizione tra intervalli ho una corrispondenza
|
||||||
|
int nCurr = 0 ;
|
||||||
|
bool bMatch = false ;
|
||||||
|
for ( auto& dataCurr : m_Values[nG][nPos]) {
|
||||||
|
if ( dataCurr.dMin < dataNew.dMax && dataNew.dMin < dataCurr.dMax) {
|
||||||
|
if ( ! vMatch.empty() && nCurr == vMatch.back().first)
|
||||||
|
bSplit = true ;
|
||||||
|
vMatch.emplace_back( nCurr, nNew) ;
|
||||||
|
bMatch = true ;
|
||||||
}
|
}
|
||||||
if ( abs( data.dMax - dPosRef) < dMinDist) {
|
++nCurr ;
|
||||||
dMinDist = abs( data.dMax - dPosRef) ;
|
}
|
||||||
ptInt.Set( itc.nI + 0.5, itc.nJ + 0.5, data.dMin) ;
|
if ( ! bMatch && ssize( vNewIntervals) > 0)
|
||||||
vtMeanN = data.vtMinN ;
|
bValidNewInterval = true ;
|
||||||
bFound = true ;
|
++ nNew ;
|
||||||
|
}
|
||||||
|
bool bEnoughIntervals = bHaveRef ? ssize( vNewIntervals) > 0 : ssize( vNewIntervals) >= nMinIntervals ;
|
||||||
|
if ( ssize( m_Values[nG][nPos]) == 0 && bEnoughIntervals)
|
||||||
|
bValidNewInterval = true ;
|
||||||
|
// se ho trovato almeno un intervallo senza corrispondenza devo aggiungerlo
|
||||||
|
// se ho trovato un intervallo sul corrente che matcha due intervalli nuovi allora devo spezzare quello sul corrente
|
||||||
|
if ( bValidNewInterval || bSplit) {
|
||||||
|
// se avevo un punto disaccoppiato lo uso come riferimento
|
||||||
|
if ( bHaveRef) {
|
||||||
|
// devo controllare se l'intervallo in più è quello che cercavo
|
||||||
|
// controllo anche tra le intersezioni scartate
|
||||||
|
double dMinDist = INFINITO ;
|
||||||
|
for ( const auto& data : vNewIntervals) {
|
||||||
|
if ( abs( data.dMin - dPosRef) < dMinDist) {
|
||||||
|
dMinDist = abs( data.dMin - dPosRef) ;
|
||||||
|
ptInt.Set( itc.nI + 0.5, itc.nJ + 0.5, data.dMax) ;
|
||||||
|
vtMeanN = data.vtMaxN ;
|
||||||
|
bFound = true ;
|
||||||
|
}
|
||||||
|
if ( abs( data.dMax - dPosRef) < dMinDist) {
|
||||||
|
dMinDist = abs( data.dMax - dPosRef) ;
|
||||||
|
ptInt.Set( itc.nI + 0.5, itc.nJ + 0.5, data.dMin) ;
|
||||||
|
vtMeanN = data.vtMinN ;
|
||||||
|
bFound = true ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for ( const auto& dU : vDiscardedInters) {
|
||||||
|
if ( abs( dU - dPosRef) < dMinDist) {
|
||||||
|
bFound = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bFound = true ;
|
||||||
|
if ( ssize( m_Values[nG][nPos]) == 0 || ! bSplit) {
|
||||||
|
// se non avevo intervalli sul corrente tengo tutto quello trovo
|
||||||
|
bAddAllIntervals = true ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// altrimenti mi aspetto di aver attraversato due fessure e quindi di avere sullo spillone corrente un
|
||||||
|
// intervallo il cui inizio e fine corrispondono a inizio di un intervallo e fine del successivo
|
||||||
|
INTVECTOR vErase ;
|
||||||
|
for ( int z = 1 ; z < ssize( vMatch) ; ++z) {
|
||||||
|
if ( vMatch[z].first == vMatch[z-1].first) {
|
||||||
|
vErase.push_back( vMatch[z].first) ;
|
||||||
|
Data& data = vNewIntervals[vMatch[z-1].second] ;
|
||||||
|
Data& dataNext = vNewIntervals[vMatch[z].second] ;
|
||||||
|
m_Values[nG][nPos].emplace_back() ;
|
||||||
|
m_Values[nG][nPos].emplace_back() ;
|
||||||
|
Data& dataCurr = m_Values[nG][nPos][vMatch[z].first] ;
|
||||||
|
// primo
|
||||||
|
m_Values[nG][nPos].end()[-2].dMin = dataCurr.dMin;
|
||||||
|
m_Values[nG][nPos].end()[-2].dMax = data.dMax ;
|
||||||
|
m_Values[nG][nPos].end()[-2].vtMinN = dataCurr.vtMinN ;
|
||||||
|
m_Values[nG][nPos].end()[-2].vtMaxN = data.vtMaxN ;
|
||||||
|
m_Values[nG][nPos].end()[-2].nToolMin = 0 ;
|
||||||
|
m_Values[nG][nPos].end()[-2].nToolMax = 0 ;
|
||||||
|
m_Values[nG][nPos].end()[-2].nCompo = 0 ;
|
||||||
|
// secondo
|
||||||
|
m_Values[nG][nPos].end()[-1].dMin = dataNext.dMin;
|
||||||
|
m_Values[nG][nPos].end()[-1].dMax = dataCurr.dMax ;
|
||||||
|
m_Values[nG][nPos].end()[-1].vtMinN = dataNext.vtMinN ;
|
||||||
|
m_Values[nG][nPos].end()[-1].vtMaxN = dataCurr.vtMaxN ;
|
||||||
|
m_Values[nG][nPos].end()[-1].nToolMin = 0 ;
|
||||||
|
m_Values[nG][nPos].end()[-1].nToolMax = 0 ;
|
||||||
|
m_Values[nG][nPos].end()[-1].nCompo = 0 ;
|
||||||
|
++z ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cancello gli intervalli che sono stati splittati
|
||||||
|
for ( int z : views::reverse( vErase))
|
||||||
|
m_Values[nG][nPos].erase( m_Values[nG][nPos].begin() + z) ;
|
||||||
|
}
|
||||||
|
// cancello gli intervalli per cui avevo già un corrispettivo sul corrente, a meno che non sia una doppia corrispondenza
|
||||||
|
// in quel caso devo spezzare l'intervallo sul corrente
|
||||||
|
// prima elimino i doppioni da vMatch
|
||||||
|
for ( int z = ssize( vMatch) - 1 ; z > 0; --z) {
|
||||||
|
if ( vMatch[z].second == vMatch[z-1].second)
|
||||||
|
vMatch.erase( vMatch.begin() + z) ;
|
||||||
|
}
|
||||||
|
for ( auto [ nCurr, nNew] : views::reverse( vMatch))
|
||||||
|
vNewIntervals.erase( vNewIntervals.begin() + nNew) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bFound)
|
if ( bFound)
|
||||||
@@ -1319,43 +1471,170 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE
|
|||||||
if ( bFound)
|
if ( bFound)
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
// se cercando nei d'intorni dello spillone non ho trovato l'intersezione mancante, mi arrendo
|
// se cercando nei dintorni dello spillone non ho trovato l'intersezione mancante, mi arrendo
|
||||||
if ( ! bFound)
|
if ( ! bFound)
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
|
|
||||||
double dMin, dMax ;
|
|
||||||
Vector3d vtMinN, vtMaxN ;
|
if ( ! bAddAllIntervals && bHaveRef) {
|
||||||
if ( itc.dU < ptInt.z) {
|
double dMin, dMax ;
|
||||||
dMin = itc.dU ;
|
Vector3d vtMinN, vtMaxN ;
|
||||||
dMax = ptInt.z ;
|
if ( itc.dU < ptInt.z) {
|
||||||
vtMinN = itc.vtN ;
|
dMin = itc.dU ;
|
||||||
vtMaxN = vtMeanN ;
|
dMax = ptInt.z ;
|
||||||
|
vtMinN = itc.vtN ;
|
||||||
|
vtMaxN = vtMeanN ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dMin = ptInt.z ;
|
||||||
|
dMax = itc.dU ;
|
||||||
|
vtMinN = vtMeanN ;
|
||||||
|
vtMaxN = itc.vtN ;
|
||||||
|
}
|
||||||
|
// prima di aggiungere il tratto verifico che non si sovrapponga con un tratto già presente
|
||||||
|
bool bAdd = true ;
|
||||||
|
for ( const auto& data: m_Values[nG][nPos]) {
|
||||||
|
if ( dMin < data.dMax && data.dMin < dMax) {
|
||||||
|
bAdd = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bAdd) {
|
||||||
|
m_Values[nG][nPos].emplace_back() ;
|
||||||
|
m_Values[nG][nPos].back().dMin = dMin;
|
||||||
|
m_Values[nG][nPos].back().dMax = dMax ;
|
||||||
|
m_Values[nG][nPos].back().vtMinN = vtMinN ;
|
||||||
|
m_Values[nG][nPos].back().vtMaxN = vtMaxN ;
|
||||||
|
m_Values[nG][nPos].back().nToolMin = 0 ;
|
||||||
|
m_Values[nG][nPos].back().nToolMax = 0 ;
|
||||||
|
m_Values[nG][nPos].back().nCompo = 0 ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dMin = ptInt.z ;
|
for ( const auto& dataNew: vNewIntervals) {
|
||||||
dMax = itc.dU ;
|
// prima di aggiungere il tratto verifico che non si sovrapponga con un tratto già presente
|
||||||
vtMinN = vtMeanN ;
|
bool bAdd = true ;
|
||||||
vtMaxN = itc.vtN ;
|
for ( const auto& data: m_Values[nG][nPos]) {
|
||||||
|
if ( dataNew.dMin < data.dMax && data.dMin < dataNew.dMax) {
|
||||||
|
bAdd = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bAdd) {
|
||||||
|
m_Values[nG][nPos].emplace_back() ;
|
||||||
|
m_Values[nG][nPos].back().dMin = dataNew.dMin;
|
||||||
|
m_Values[nG][nPos].back().dMax = dataNew.dMax ;
|
||||||
|
m_Values[nG][nPos].back().vtMinN = dataNew.vtMinN ;
|
||||||
|
m_Values[nG][nPos].back().vtMaxN = dataNew.vtMaxN ;
|
||||||
|
m_Values[nG][nPos].back().nToolMin = 0 ;
|
||||||
|
m_Values[nG][nPos].back().nToolMax = 0 ;
|
||||||
|
m_Values[nG][nPos].back().nCompo = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//// prima di aggiungere il tratto verifico che non si sovrapponga con un tratto già presente
|
|
||||||
//for ( const auto& data: m_Values[nG][nPos]) {
|
|
||||||
// if ( ( dMin > data.dMin && dMin < data.dMax) ||
|
|
||||||
// ( dMax > data.dMin && dMax < data.dMax) ||
|
|
||||||
// ( dMin < data.dMin && dMax > data.dMax))
|
|
||||||
// continue ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
m_Values[nG][nPos].emplace_back() ;
|
|
||||||
m_Values[nG][nPos].back().dMin = dMin;
|
|
||||||
m_Values[nG][nPos].back().dMax = dMax ;
|
|
||||||
m_Values[nG][nPos].back().vtMinN = vtMinN ;
|
|
||||||
m_Values[nG][nPos].back().vtMaxN = vtMaxN ;
|
|
||||||
m_Values[nG][nPos].back().nToolMin = 0 ;
|
|
||||||
m_Values[nG][nPos].back().nToolMax = 0 ;
|
|
||||||
m_Values[nG][nPos].back().nCompo = 0 ;
|
|
||||||
std::sort( m_Values[nG][nPos].begin(), m_Values[nG][nPos].end(), []( Data& a, Data& b) { return a.dMin < b.dMin ;}) ;
|
std::sort( m_Values[nG][nPos].begin(), m_Values[nG][nPos].end(), []( Data& a, Data& b) { return a.dMin < b.dMin ;}) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ad ogni lato assegno un bit
|
||||||
|
enum NeighSide {
|
||||||
|
BOTTOM = 1 << 0,
|
||||||
|
RIGHT = 1 << 1,
|
||||||
|
TOP = 1 << 2,
|
||||||
|
LEFT = 1 << 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// con una mask verifico se due punti stanno sullo stesso lato
|
||||||
|
bool AreOnSameEdge( int a, int b)
|
||||||
|
{
|
||||||
|
static const int mask[9] = {
|
||||||
|
BOTTOM | LEFT, // 0
|
||||||
|
BOTTOM, // 1
|
||||||
|
BOTTOM | RIGHT, // 2
|
||||||
|
LEFT, // 3
|
||||||
|
0, // 4 (centro)
|
||||||
|
RIGHT, // 5
|
||||||
|
TOP | LEFT, // 6
|
||||||
|
TOP, // 7
|
||||||
|
TOP | RIGHT // 8
|
||||||
|
};
|
||||||
|
|
||||||
|
return ( mask[a] & mask[b]) != 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int position[9] =
|
||||||
|
{
|
||||||
|
0, // 0
|
||||||
|
1, // 1
|
||||||
|
2, // 2
|
||||||
|
7, // 3
|
||||||
|
-1, // 4 (centro)
|
||||||
|
3, // 5
|
||||||
|
6, // 6
|
||||||
|
5, // 7
|
||||||
|
4 // 8
|
||||||
|
} ;
|
||||||
|
|
||||||
|
bool AreOpposite( int a, int b)
|
||||||
|
{
|
||||||
|
// a partire da un punto cosidero suoi opposti l'opposto geometrico e i suoi vicini
|
||||||
|
// quindi i punti a distanza 3,4,5 salti dal punto di partenza
|
||||||
|
int pa = position[a] ;
|
||||||
|
int pb = position[b] ;
|
||||||
|
|
||||||
|
if ( pa == -1 || pb == -1)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
int d = ( pb - pa + 8) % 8 ;
|
||||||
|
|
||||||
|
return d == 3 || d == 4 || d == 5 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AreOpposite2( int a, int b)
|
||||||
|
{
|
||||||
|
return a + b == 8 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
VolZmap::SearchMissingIntervals( int nMap, INTTOCHECKVEC& vIntToCheck)
|
||||||
|
{
|
||||||
|
|
||||||
|
for ( int nI = 0 ; nI < m_nNx[nMap] ; ++nI) {
|
||||||
|
for ( int nJ = 0 ; nJ < m_nNy[nMap] ; ++nJ) {
|
||||||
|
int nPos = int( nJ) * m_nNx[nMap] + int( nI) ;
|
||||||
|
vector<Neigh> vNeigh = GetNeighbours( nMap, nI, nJ, 1) ;
|
||||||
|
if ( ssize( m_Values[nMap][nPos]) > 0) {
|
||||||
|
// se tra i vicini ne trovo uno con lo stesso numero di intervalli allora il corrente è a posto
|
||||||
|
// sennò devo analizzarlo
|
||||||
|
bool bFoundAlike = false ;
|
||||||
|
for ( const auto& [i,j,n] : vNeigh) {
|
||||||
|
int nNeighPos = int( j) * m_nNx[nMap] + int( i) ;
|
||||||
|
if ( ssize( m_Values[nMap][nNeighPos]) == ssize( m_Values[nMap][nPos])) {
|
||||||
|
bFoundAlike = true ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! bFoundAlike)
|
||||||
|
vIntToCheck.emplace_back( P_INVALID, V_INVALID, double( NAN), nMap, nI, nJ) ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
INTVECTOR nNeighTrig ;
|
||||||
|
for ( const auto& [i,j,n] : vNeigh) {
|
||||||
|
int nNeighPos = int( j) * m_nNx[nMap] + int( i) ;
|
||||||
|
if ( ssize( m_Values[nMap][nNeighPos]) > ssize( m_Values[nMap][nPos])) {
|
||||||
|
nNeighTrig.push_back( n) ;
|
||||||
|
if ( ! nNeighTrig.empty() && any_of( nNeighTrig.begin(), nNeighTrig.end(), [n]( int nNeigh) { return AreOpposite2( nNeigh, n) ;})) {
|
||||||
|
vIntToCheck.emplace_back( P_INVALID, V_INVALID, double( NAN), nMap, nI, nJ) ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
+2
-2
@@ -36,7 +36,7 @@ using namespace std ;
|
|||||||
static const int MAX_FAN_BASE_VERTS = 7 ;
|
static const int MAX_FAN_BASE_VERTS = 7 ;
|
||||||
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor, MAX_FAN_BASE_VERTS, 3> SvdMatrix ;
|
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor, MAX_FAN_BASE_VERTS, 3> SvdMatrix ;
|
||||||
typedef Eigen::Matrix<double, Eigen::Dynamic, 1, Eigen::ColMajor, MAX_FAN_BASE_VERTS, 1> SvdVector ;
|
typedef Eigen::Matrix<double, Eigen::Dynamic, 1, Eigen::ColMajor, MAX_FAN_BASE_VERTS, 1> SvdVector ;
|
||||||
typedef Eigen::JacobiSVD<SvdMatrix, Eigen::QRPreconditioners::ColPivHouseholderQRPreconditioner> SvdDecomposer ;
|
typedef Eigen::JacobiSVD<SvdMatrix, Eigen::ComputeThinU | Eigen::ComputeThinV> SvdDecomposer ;
|
||||||
|
|
||||||
// ------------------------- FUNZIONE TEST SULLE NORMALI --------------------------------------------------------------------------
|
// ------------------------- FUNZIONE TEST SULLE NORMALI --------------------------------------------------------------------------
|
||||||
enum FatureType { NO_FEATURE = 0, CORNER = 1, EDGE = 2} ;
|
enum FatureType { NO_FEATURE = 0, CORNER = 1, EDGE = 2} ;
|
||||||
@@ -2036,7 +2036,7 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calcolo SVD
|
// calcolo SVD
|
||||||
SvdDecomposer svd( dMatrixN, Eigen::ComputeThinU | Eigen::ComputeThinV) ;
|
SvdDecomposer svd( dMatrixN) ;
|
||||||
const auto& dSingularValue = svd.singularValues() ;
|
const auto& dSingularValue = svd.singularValues() ;
|
||||||
const auto& dMatrixV = svd.matrixV() ;
|
const auto& dMatrixV = svd.matrixV() ;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user