diff --git a/DistPointSurfBz.cpp b/DistPointSurfBz.cpp index 0495786..81f6f17 100644 --- a/DistPointSurfBz.cpp +++ b/DistPointSurfBz.cpp @@ -55,7 +55,7 @@ DistPointSurfBz::Calculate( const Point3d& ptP, const ISurfBezier& srfBz) //salvo il punto corrispondente nel parametrico srfBz.UnprojectPointFromStm( nT, ptMinTm, m_ptParam) ; // salvo il punto a minima distanza sulla superficie e la normale alla superficie in quel punto - srfBz.GetPointNrmD1D2( m_ptParam.x / SBZ_TREG_COEFF, m_ptParam.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, m_ptMinDistPoint, m_vtN) ; + srfBz.GetPointNrmD1D2( m_ptParam.x, m_ptParam.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, m_ptMinDistPoint, m_vtN) ; // salvo la distanza minima m_dDist = Dist( ptP, m_ptMinDistPoint) ; diff --git a/IntersLineSurfBez.cpp b/IntersLineSurfBez.cpp index d6dce45..09c7dab 100644 --- a/IntersLineSurfBez.cpp +++ b/IntersLineSurfBez.cpp @@ -34,7 +34,6 @@ RefineIntersNewton( const Point3d& ptL, const Vector3d& vtL, double dLen, bool b const ISurfBezier* pSurfBz, Point3d& ptSP, Point3d& ptIBz) { // la funzione raffina la posisione del punto ptSP, minimizzando la distanza dalla retta e restituisce il punto di intersezione ptIBz - pSurfBz->GetPointD1D2( ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ; // usando un algoritmo di newton cerco di avvicinarmi il più possibile alla retta DistPointLine dpl( ptIBz, ptL, vtL, dLen, bFinite) ; double dDistNew = 0, dDistPre = 0 ; @@ -48,18 +47,18 @@ RefineIntersNewton( const Point3d& ptL, const Vector3d& vtL, double dLen, bool b while ( dDistNew > EPS_SMALL && nCount < 100) { dDistPre = dDistNew ; Point3d ptIBzNew1 ; - pSurfBz->GetPointD1D2( ( ptSP.x + dh) / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ; + pSurfBz->GetPointD1D2( ( ptSP.x + dh), ptSP.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ; DistPointLine dplNewU( ptIBzNew1, ptL, vtL, dLen, bFinite) ; dplNewU.GetDist( dDistNew) ; double dfdU = ( dDistNew - dDistPre) / dh ; Point3d ptIBzNew2 ; - pSurfBz->GetPointD1D2( ptSP.x / SBZ_TREG_COEFF, ( ptSP.y + dh) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ; + pSurfBz->GetPointD1D2( ptSP.x, ( ptSP.y + dh), ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ; DistPointLine dplNewV( ptIBzNew2, ptL, vtL, dLen, bFinite) ; dplNewV.GetDist( dDistNew) ; double dfdV = ( dDistNew - dDistPre) / dh ; // mi avvicino cercando di annullare la distanza in un colpo solo double dr = - dDistPre / ( dfdU + dfdV) ; - pSurfBz->GetPointD1D2(( ptSP.x + dr * dfdU) / SBZ_TREG_COEFF, ( ptSP.y + dr * dfdV) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ; + pSurfBz->GetPointD1D2(( ptSP.x + dr * dfdU), ( ptSP.y + dr * dfdV), ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ; DistPointLine dplNew( ptIBz, ptL, vtL, dLen, bFinite) ; dplNew.GetDist( dDistNew) ; ++ nCount ; @@ -148,7 +147,7 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS return false ; } Vector3d vtN ; - pSurfBz->GetPointNrmD1D2(ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz, vtN) ; + pSurfBz->GetPointNrmD1D2(ptSP.x, ptSP.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz, vtN) ; double dCos = vtN * vtL ; double dCos2 = 0 ; // eventualmente ripeto tutto per ptI2 ( se ho un'intersezione con sovrapposizione) @@ -163,7 +162,7 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz)) return false ; } - pSurfBz->GetPointNrmD1D2( ptSP2.x / SBZ_TREG_COEFF, ptSP2.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz2, vtN) ; + pSurfBz->GetPointNrmD1D2( ptSP2.x, ptSP2.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz2, vtN) ; dCos2 = vtN * vtL ; } UpdateInfoIntersLineSurfBz( ptL, vtL, InfoTm.nILTT, InfoTm.nT, ptSP, ptIBz, dCos, ptSP2, ptIBz2, dCos2, vInfo) ; diff --git a/SurfBezier.cpp b/SurfBezier.cpp index a2562ef..82f2ca1 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -2255,14 +2255,14 @@ SurfBezier::IncreaseUV( double& dUV, double dxy, bool bUOrV, double* dUVCopy, bo if ( bUOrV) { if ( dUVTest < 0) dUVTest = 0 ; - else if ( dUVTest > m_nSpanU * SBZ_TREG_COEFF ) - dUVTest = m_nSpanU * SBZ_TREG_COEFF ; + else if ( dUVTest > m_nSpanU ) + dUVTest = m_nSpanU ; } else { if ( dUVTest < 0) dUVTest = 0 ; - else if ( dUVTest > m_nSpanV * SBZ_TREG_COEFF ) - dUVTest = m_nSpanV * SBZ_TREG_COEFF ; + else if ( dUVTest > m_nSpanV ) + dUVTest = m_nSpanV ; } if ( bModifyOrig) dUV = dUVTest ; @@ -2930,9 +2930,9 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in bool bNearPole = false ; // devo capire se il triangolo di riferimento ha un vertice in un polo INTVECTOR vInters(4) ; fill( vInters.begin(), vInters.end(), 0) ; - // se il vettore dei poli non è stato riempito vuol dire che quando è stata creata la superficie non è stata chiamata la funzione CalcPoles - if ( int( m_vbPole.size()) == 0) - return false ; + // se necessario calcolo i poli + if ( m_vbPole.empty()) + CalcPoles() ; if ( m_vbPole[0] || m_vbPole[1] || m_vbPole[2] || m_vbPole[3] || m_bClosedU || m_bClosedV) { // scorro sugli edge for ( int c = 0 ; c < 4 ; ++c) { @@ -2972,9 +2972,9 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in int nVert[3] ; pSurfTm->GetTriangle( nTriaIndex, nVert) ; PNTVECTOR vPtPa(3) ; - pSurfTm->GetVertexParam( nVert[0], vPtPa[0].x,vPtPa[0].y) ; - pSurfTm->GetVertexParam( nVert[1], vPtPa[1].x,vPtPa[1].y) ; - pSurfTm->GetVertexParam( nVert[2], vPtPa[2].x,vPtPa[2].y) ; + pSurfTm->GetVertexParam( nVert[0], vPtPa[0].x,vPtPa[0].y, false) ; + pSurfTm->GetVertexParam( nVert[1], vPtPa[1].x,vPtPa[1].y, false) ; + pSurfTm->GetVertexParam( nVert[2], vPtPa[2].x,vPtPa[2].y, false) ; PNTVECTOR vPT(3) ; pSurfTm->GetVertex( nVert[0], vPT[0]) ; pSurfTm->GetVertex( nVert[1], vPT[1]) ; @@ -3189,6 +3189,8 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in ptSP = vPtPa[1] ; else if ( AreSamePointApprox(ptI, vPT[2])) ptSP = vPtPa[2] ; + // restituisco il punto nel parametrico riscalato + ptSP / SBZ_TREG_COEFF ; return true ; } // calcolo approssimativamente le coordinate nello spazio parametrico del punto di intersezione @@ -3225,8 +3227,10 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in mB.col(1) << vPtPa[1].x, vPtPa[1].y, 0 ; mB.col(2) << vPtPa[2].x, vPtPa[2].y, 0 ; Eigen::Vector3d ptParam = mB * x ; - IncreaseUV( ptSP.x, ptParam.x(), true) ; - IncreaseUV( ptSP.y, ptParam.y(), false) ; + // restituisco il punto nel parametrico riscalato + IncreaseUV( ptSP.x, ptParam.x() / SBZ_TREG_COEFF, true) ; + IncreaseUV( ptSP.y, ptParam.y() / SBZ_TREG_COEFF, false) ; + return true ; } @@ -3251,7 +3255,7 @@ SurfBezier::UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d if ( ! UnprojectPointFromStm( -1, ptI, ptParam, IntLineTriaType::ILTT_IN, ptIPrev, bThroughEdge)) return false ; Point3d ptBez ; - GetPointD1D2( ptParam.x / SBZ_TREG_COEFF, ptParam.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez) ; + GetPointD1D2( ptParam.x, ptParam.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez) ; // usando un algoritmo di newton cerco di avvicinarmi il più possibile al punto double dDistNew = pPlCut == nullptr ? Dist( pt3D, ptBez) : abs(DistPointPlane( ptBez, *pPlCut)) ; @@ -3275,16 +3279,14 @@ SurfBezier::UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d dDistPre = dDistNew ; // derivata in U Point3d ptIBzNew1 ; - //GetPointD1D2( ( ptParam.x + dh) / SBZ_TREG_COEFF, ptParam.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ; double dUh ; IncreaseUV( ptParam.x, dh, true, &dUh, false) ; - GetPointD1D2( dUh / SBZ_TREG_COEFF, ptParam.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ; + GetPointD1D2( dUh, ptParam.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ; dDist0 = pPlCut == nullptr ? Dist( pt3D, ptIBzNew1) : abs(DistPointPlane( ptIBzNew1, *pPlCut)) ; dfdU = ( dDist0 - dDistPre) / dh ; // derivata in V Point3d ptIBzNew2 ; - //GetPointD1D2( ptParam.x / SBZ_TREG_COEFF, ( ptParam.y + dh) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ; double dVh ; IncreaseUV( ptParam.y, dh, false, &dVh, false) ; - GetPointD1D2( ptParam.x / SBZ_TREG_COEFF, dVh / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ; + GetPointD1D2( ptParam.x, dVh, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ; dDist1 = pPlCut == nullptr ? Dist( pt3D, ptIBzNew2) : abs(DistPointPlane( ptIBzNew2, *pPlCut)) ; dfdV = ( dDist1 - dDistPre) / dh ; } @@ -3312,7 +3314,7 @@ SurfBezier::UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d Point3d ptCopy = ptParam ; IncreaseUV( ptParam, vtDir, nullptr, true) ; // calcolo la nuova distanza tra il punto di partenza e quello che sto trovando con le coordinate attuali - GetPointD1D2( ptParam.x / SBZ_TREG_COEFF, ptParam.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez) ; + GetPointD1D2( ptParam.x, ptParam.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez) ; dDistNew = pPlCut == nullptr ? Dist( pt3D, ptBez) : abs(DistPointPlane( ptBez, *pPlCut)) ; dApproach = dDistPre - dDistNew ; @@ -3339,16 +3341,16 @@ SurfBezier::UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d // devo distinguere il caso di un triangolo a metà dello spazio, con un vertice su un lato di polo, ma senza vertici su lati di chiusura if ( bThroughEdge != nullptr && *bThroughEdge) { if ( m_bClosedU) { - if ( ptParam.x < 1) + if ( ptParam.x < EPS_SMALL) ptParam.x = 0 ; - else if ( abs( m_nSpanU * SBZ_TREG_COEFF - ptParam.x) < 1) - ptParam.x = m_nSpanU * SBZ_TREG_COEFF ; + else if ( abs( m_nSpanU - ptParam.x) < EPS_SMALL) + ptParam.x = m_nSpanU ; } if ( m_bClosedV) { - if ( ptParam.y < 1) + if ( ptParam.y < EPS_SMALL) ptParam.y = 0 ; - else if ( abs( m_nSpanV * SBZ_TREG_COEFF - ptParam.y) < 1) - ptParam.y = m_nSpanV * SBZ_TREG_COEFF ; + else if ( abs( m_nSpanV - ptParam.y) < EPS_SMALL) + ptParam.y = m_nSpanV ; } } diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 7f05ab0..fde8ff7 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -512,14 +512,21 @@ SurfTriMesh::GetVertex( int nId, Point3d& ptP) const //---------------------------------------------------------------------------- bool -SurfTriMesh::GetVertexParam( int nId, double& dU, double& dV) const +SurfTriMesh::GetVertexParam( int nId, double& dU, double& dV, bool bDownScaled) const { // verifico esistenza del vertice if ( nId < 0 || nId >= GetVertexSize() || m_vVert[nId].nIdTria == SVT_DEL) return false ; // recupero i dati - dU = m_vVert[nId].dU ; - dV = m_vVert[nId].dV ; + int SBZ_COEFF = 1024 ; + if( bDownScaled) { + dU = m_vVert[nId].dU / SBZ_COEFF ; + dV = m_vVert[nId].dV / SBZ_COEFF ; + } + else { + dU = m_vVert[nId].dU ; + dV = m_vVert[nId].dV ; + } return true ; } diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 12c886e..5990a77 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -277,7 +277,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool GetShowEdges( void) const override { return m_bShowEdges ; } bool GetVertex( int nId, Point3d& ptP) const override ; - bool GetVertexParam( int nId, double& dU, double& dV) const override ; + bool GetVertexParam( int nId, double& dU, double& dV, bool bDownScaled = true) const override ; int GetFirstVertex( Point3d& ptP) const override ; int GetNextVertex( int nId, Point3d& ptP) const override ; bool GetTriangle( int nId, int nIdVert[3]) const override ;