From d7ec1fd30449e15b0d06d762f47a1e97ce1c282f Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Mon, 18 Sep 2023 10:21:49 +0200 Subject: [PATCH 1/5] =?UTF-8?q?EgtGeomKernel=20:=20-=20aggiunta=20delle=20?= =?UTF-8?q?coordinate=20U=20e=20V=20ai=20vertici=20delle=20TriMesh.=20Manc?= =?UTF-8?q?a=20da=20modificare=20:=20-=20funzione=20MoveVertex=20-=20surfB?= =?UTF-8?q?ezier.cpp=20quando=20verr=C3=A0=20aggiunto=20il=20ramo=20Trim&M?= =?UTF-8?q?esh.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StmFromTriangleSoup.cpp | 4 ++-- SurfTriMesh.cpp | 46 +++++++++++++++++++++++++++++++++++++++-- SurfTriMesh.h | 15 ++++++++++---- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/StmFromTriangleSoup.cpp b/StmFromTriangleSoup.cpp index 08db0c7..8c55a74 100644 --- a/StmFromTriangleSoup.cpp +++ b/StmFromTriangleSoup.cpp @@ -99,14 +99,14 @@ StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, cons //---------------------------------------------------------------------------- int -StmFromTriangleSoup::AddVertex( const Point3d& ptP) +StmFromTriangleSoup::AddVertex( const Point3d& ptP, const double dU, const double dV) { // verifico se gią presente int nId ; if ( m_VertGrid.Find( ptP, 2 * EPS_SMALL, nId)) return nId ; // aggiungo il vertice - if ( ( nId = m_pSTM->AddVertex( ptP)) == SVT_NULL) + if ( ( nId = m_pSTM->AddVertex( ptP, dU, dV)) == SVT_NULL) return SVT_NULL ; m_VertGrid.InsertPoint( ptP, nId) ; return nId ; diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 76ad9e9..d171748 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -107,7 +107,7 @@ SurfTriMesh::Clear( void) //---------------------------------------------------------------------------- int -SurfTriMesh::AddVertex( const Point3d& ptVert) +SurfTriMesh::AddVertex( const Point3d& ptVert, const double dU, const double dV) { // imposto ricalcolo m_nStatus = TO_VERIFY ; @@ -118,7 +118,11 @@ SurfTriMesh::AddVertex( const Point3d& ptVert) try { m_vVert.emplace_back( ptVert) ;} catch(...) { return SVT_NULL ;} // ne determino l'indice - return int( m_vVert.size() - 1) ; + int nId = int( m_vVert.size() - 1) ; + // aggiugo le coordinate corrispondenti allo spazio parametrico + m_vVert[nId].dU = dU ; + m_vVert[nId].dV = dV ; + return nId ; } //---------------------------------------------------------------------------- @@ -475,6 +479,19 @@ SurfTriMesh::GetVertex( int nId, Point3d& ptP) const return true ; } +//---------------------------------------------------------------------------- +bool +SurfTriMesh::GetVertexParam( int nId, double& dU, double& dV) 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 ; + return true ; +} + //---------------------------------------------------------------------------- int SurfTriMesh::GetFirstVertex( Point3d& ptP) const @@ -482,6 +499,13 @@ SurfTriMesh::GetFirstVertex( Point3d& ptP) const return GetNextVertex( SVT_NULL, ptP) ; } +//---------------------------------------------------------------------------- +int +SurfTriMesh::GetFirstVertexParam( int nId, double& dU, double& dV) const +{ + return GetNextVertexParam( SVT_NULL, dU, dV) ; +} + //---------------------------------------------------------------------------- int SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const @@ -499,6 +523,24 @@ SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const return nId ; } +//---------------------------------------------------------------------------- +int +SurfTriMesh::GetNextVertexParam( int nId, double& dU, double& dV) const +{ + // cerco il primo successivo valido + do { + nId ++ ; + } while ( nId < GetVertexSize() && m_vVert[nId].nIdTria == SVT_DEL) ; + // se oltrepassata fine + if ( nId >= GetVertexSize()) + return SVT_NULL ; + // recupero i dati + dU = m_vVert[nId].dU ; + dV = m_vVert[nId].dV ; + // ritorno indice triangolo corrente + return nId ; +} + //---------------------------------------------------------------------------- bool SurfTriMesh::GetTriangle( int nId, int nIdVert[3]) const diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 6ae2946..9f8c8d1 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -28,11 +28,15 @@ class SurfFlatRegion ; class StmVert { public : - StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {} - StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {} - StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF), nTemp( 0) {} + StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0), dU( -1), dV( -1) {} + StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0), dU( -1), dV( -1) {} + StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF), nTemp( 0), dU( -1), dV( -1) {} public : Point3d ptP ; + double dU ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x nSpanV) + // della sup di Bezier // -1 se non definito + double dV ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x nSpanV) + // della sup di Bezier // -1 se non definito int nIdTria ; int nFlag ; mutable int nTemp ; @@ -215,7 +219,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW { m_dSmoothAng = std::max( dSmoothAngDeg, EPS_ANG_SMALL) ; m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ; m_OGrMgr.Reset() ; } - int AddVertex( const Point3d& ptVert) override ; + int AddVertex( const Point3d& ptVert, const double dU = -1 , const double dV = -1) override ; bool MoveVertex( int nInd, const Point3d& ptNewVert) override ; int AddTriangle( const int nIdVert[3], int nTFlag = 0) override ; bool RemoveTriangle( int nId) override ; @@ -244,8 +248,11 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW double GetSmoothAngle( void) const override { return m_dSmoothAng ; } bool GetVertex( int nId, Point3d& ptP) const override ; + bool GetVertexParam( int nId, double& dU, double& dV) const override ; int GetFirstVertex( Point3d& ptP) const override ; + int GetFirstVertexParam( int nId, double& dU, double& dV) const override ; int GetNextVertex( int nId, Point3d& ptP) const override ; + int GetNextVertexParam( int nId, double& dU, double& dV) const override ; bool GetTriangle( int nId, int nIdVert[3]) const override ; int GetFirstTriangle( int nIdVert[3]) const override ; int GetNextTriangle( int nId, int nIdVert[3]) const override ; From a3531c484127b5b76172d219cecfc30325f358d5 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Mon, 18 Sep 2023 10:33:50 +0200 Subject: [PATCH 2/5] EgtGeomKernel : - correzione su coordinate U e V ai vertici delle TriMesh. --- StmFromTriangleSoup.cpp | 9 +++++---- SurfTriMesh.h | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/StmFromTriangleSoup.cpp b/StmFromTriangleSoup.cpp index 8c55a74..87bae4e 100644 --- a/StmFromTriangleSoup.cpp +++ b/StmFromTriangleSoup.cpp @@ -76,18 +76,19 @@ StmFromTriangleSoup::AddTriangle( const Triangle3d& Tria) //---------------------------------------------------------------------------- bool -StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2) +StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2, + const double dU0, const double dV0,const double dU1, const double dV1,const double dU2, const double dV2) { // verifico inizializzazione if ( m_pSTM == nullptr) return false ; // ciclo sui tre vertici int nIdV[3] ; - if ( ( nIdV[0] = AddVertex( ptP0)) == SVT_NULL) + if ( ( nIdV[0] = AddVertex( ptP0, dU0, dV0)) == SVT_NULL) return false ; - if ( ( nIdV[1] = AddVertex( ptP1)) == SVT_NULL) + if ( ( nIdV[1] = AddVertex( ptP1, dU1, dV1)) == SVT_NULL) return false ; - if ( ( nIdV[2] = AddVertex( ptP2)) == SVT_NULL) + if ( ( nIdV[2] = AddVertex( ptP2, dU2, dV2)) == SVT_NULL) return false ; // se i vertici sono tutti diversi tra loro, inserisco il triangolo if ( nIdV[0] != nIdV[1] && nIdV[0] != nIdV[2] && nIdV[1] != nIdV[2]) { diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 9f8c8d1..69b8a8a 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -33,9 +33,9 @@ class StmVert StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF), nTemp( 0), dU( -1), dV( -1) {} public : Point3d ptP ; - double dU ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x nSpanV) + double dU ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x 1000) ( nSpanV x 1000) // della sup di Bezier // -1 se non definito - double dV ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x nSpanV) + double dV ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x 1000) ( nSpanV x 1000) // della sup di Bezier // -1 se non definito int nIdTria ; int nFlag ; From b4058ad363290a6f2f25804bfc7b2c4990fc5203 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 8 Feb 2024 09:28:49 +0100 Subject: [PATCH 3/5] EgtGeomKernel : - aggiunta delle intersezioni tra linee e SupBez. --- EgtGeomKernel.vcxproj | 2 + IntersLineSurfBez.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++ IntersLineSurfBez.h | 1 + SurfTriMesh.h | 2 - 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 IntersLineSurfBez.cpp create mode 100644 IntersLineSurfBez.h diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 8c884bb..ebcb8d6 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -309,6 +309,7 @@ copy $(TargetPath) \EgtProg\Dll64 + @@ -449,6 +450,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/IntersLineSurfBez.cpp b/IntersLineSurfBez.cpp new file mode 100644 index 0000000..080d110 --- /dev/null +++ b/IntersLineSurfBez.cpp @@ -0,0 +1,108 @@ +//---------------------------------------------------------------------------- +// EgalTech 2024 +//---------------------------------------------------------------------------- +// File : IntersLineSurfBez.cpp Data : 06.02.24 Versione : 2.6b1 +// Contenuto : Implementazione della intersezione linea/superficie bezier. +// +// +// +// Modifiche : 06.02.24 DB Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "IntersLineBox.h" +#include "/EgtDev/Include/EGkIntersLineTria.h" +#include "/EgtDev/Include/EGkIntersLineSurfTm.h" +#include "/EgtDev/Include/EGkIntersLineSurfBez.h" +#include "/EgtDev/Include/EGkSurfBezier.h" + +using namespace std ; + +//---------------------------------------------------------------------------- +// Intersezione di una linea con una superficie TriMesh +//---------------------------------------------------------------------------- +bool +IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfBezier& SBz, + ILSBIVECTOR& vInfo, bool bFinite) +{ + // verifico linea + Vector3d vtDir = vtL ; + if ( ! vtDir.Normalize( EPS_ZERO)) + return false ; + // verifico superficie + if ( &SBz == nullptr) + return false ; + // verifico parametro di ritorno + if ( &vInfo == nullptr) + return false ; + vInfo.clear() ; + + // trovo le intersezioni con la trimesh ausiliaria + const ISurfTriMesh* pSurfTm = SBz.GetAuxSurf() ; + ILSIVECTOR vInfoTm ; + if ( ! IntersLineSurfTm( ptL, vtL, dLen, *pSurfTm, vInfoTm, bFinite)) + return false ; + + // ricavo le intersezioni con la superficie di Bezier + for ( IntLinStmInfo InfoTm : vInfoTm ) { + int nIL, nTT ; + double dUU, dUU2, dCos ; + Point3d ptP, ptP2, ptSP, ptSP2 ; + IntLinSbzInfo InfoBz( InfoTm.nILTT, dUU, dUU2, nTT, dCos, ptP, ptP2, ptSP, ptSP2) ; + vInfo.emplace_back( InfoBz) ; + } + + //////////////////////////////////////////////////////// interlineSurfTm + + + // limito la linea al box dei triangoli della superficie + BBox3d b3Stm = Stm.GetAllTriaBox() ; + if ( b3Stm.IsEmpty()) + return false ; + // lo ingrandisco per non avere problemi con faccia piana su piani canonici + b3Stm.Expand( 10 * EPS_SMALL) ; + double dU1, dU2 ; + if ( ! IntersLineBox( ptL, vtL, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2)) + return true ; + if ( bFinite) { + dU1 = max( dU1, 0.) ; + dU2 = min( dU2, dLen) ; + if ( dU2 - dU1 < EPS_SMALL) + return true ; + } + Point3d ptStart = ptL + dU1 * vtL ; + double dLenEff = dU2 - dU1 ; + // cerco i triangoli intersecati dalla linea + const double BOX_STEP = 10 ; + int nStep = int( ceil( dLenEff / BOX_STEP)) ; + Vector3d vtStep = dLenEff / nStep * vtL ; + INTVECTOR vPrevT ; + for ( int i = 0 ; i < nStep ; ++ i) { + BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ; + INTVECTOR vT ; + if ( Stm.GetAllTriaOverlapBox( b3Box, vT)) { + for ( auto nT : vT) { + if ( find( vPrevT.begin(), vPrevT.end(), nT) == vPrevT.end()) { + vPrevT.emplace_back( nT) ; + Triangle3d Tria ; + Stm.GetTriangle( nT, Tria) ; + // aggiorno info con intersezione + UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ; + } + } + } + } + + // ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea + OrderInfoIntersLineSurfTm( vInfo) ; + + return true ; + + //////////////////////////////////////////////////////// interlineSurfTm + + + return true ; +} \ No newline at end of file diff --git a/IntersLineSurfBez.h b/IntersLineSurfBez.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/IntersLineSurfBez.h @@ -0,0 +1 @@ +#pragma once diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 12e4efe..e78f3f5 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -257,9 +257,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool GetVertex( int nId, Point3d& ptP) const override ; bool GetVertexParam( int nId, double& dU, double& dV) const override ; int GetFirstVertex( Point3d& ptP) const override ; - int GetFirstVertexParam( int nId, double& dU, double& dV) const override ; int GetNextVertex( int nId, Point3d& ptP) const override ; - int GetNextVertexParam( int nId, double& dU, double& dV) const override ; bool GetTriangle( int nId, int nIdVert[3]) const override ; int GetFirstTriangle( int nIdVert[3]) const override ; int GetNextTriangle( int nId, int nIdVert[3]) const override ; From 2c159d7ce6a05b1d1e9547f1283f9a697e868cdd Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 8 Feb 2024 12:02:12 +0100 Subject: [PATCH 4/5] EgtGeomKernel : - aggiunta funzione di raffinamento dei punti di intersezione per Bezier. --- IntersLineSurfBez.cpp | 114 ++++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 43 deletions(-) diff --git a/IntersLineSurfBez.cpp b/IntersLineSurfBez.cpp index 080d110..3637788 100644 --- a/IntersLineSurfBez.cpp +++ b/IntersLineSurfBez.cpp @@ -18,6 +18,7 @@ #include "/EgtDev/Include/EGkIntersLineSurfTm.h" #include "/EgtDev/Include/EGkIntersLineSurfBez.h" #include "/EgtDev/Include/EGkSurfBezier.h" +#include "/EgtDev/Extern/Eigen/Dense" using namespace std ; @@ -48,61 +49,88 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS // ricavo le intersezioni con la superficie di Bezier for ( IntLinStmInfo InfoTm : vInfoTm ) { - int nIL, nTT ; + // devo raffinare i parametri lungo la curva, l'angolo e i punti di intersezione double dUU, dUU2, dCos ; - Point3d ptP, ptP2, ptSP, ptSP2 ; - IntLinSbzInfo InfoBz( InfoTm.nILTT, dUU, dUU2, nTT, dCos, ptP, ptP2, ptSP, ptSP2) ; + Point3d ptI, ptI2 ; + // devo trovare le intersezioni + Point3d ptSP, ptSP2 ; + RefinePoints( pSurfTm, InfoTm.nILTT, InfoTm.nT, ptI, ptI2,ptSP, ptSP2) ; + IntLinSbzInfo InfoBz( InfoTm.nILTT, dUU, dUU2, InfoTm.nT, dCos, InfoTm.ptI, InfoTm.ptI2, ptSP, ptSP2) ; vInfo.emplace_back( InfoBz) ; } //////////////////////////////////////////////////////// interlineSurfTm - // limito la linea al box dei triangoli della superficie - BBox3d b3Stm = Stm.GetAllTriaBox() ; - if ( b3Stm.IsEmpty()) - return false ; - // lo ingrandisco per non avere problemi con faccia piana su piani canonici - b3Stm.Expand( 10 * EPS_SMALL) ; - double dU1, dU2 ; - if ( ! IntersLineBox( ptL, vtL, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2)) - return true ; - if ( bFinite) { - dU1 = max( dU1, 0.) ; - dU2 = min( dU2, dLen) ; - if ( dU2 - dU1 < EPS_SMALL) - return true ; - } - Point3d ptStart = ptL + dU1 * vtL ; - double dLenEff = dU2 - dU1 ; - // cerco i triangoli intersecati dalla linea - const double BOX_STEP = 10 ; - int nStep = int( ceil( dLenEff / BOX_STEP)) ; - Vector3d vtStep = dLenEff / nStep * vtL ; - INTVECTOR vPrevT ; - for ( int i = 0 ; i < nStep ; ++ i) { - BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ; - INTVECTOR vT ; - if ( Stm.GetAllTriaOverlapBox( b3Box, vT)) { - for ( auto nT : vT) { - if ( find( vPrevT.begin(), vPrevT.end(), nT) == vPrevT.end()) { - vPrevT.emplace_back( nT) ; - Triangle3d Tria ; - Stm.GetTriangle( nT, Tria) ; - // aggiorno info con intersezione - UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ; - } - } - } - } + //// limito la linea al box dei triangoli della superficie + // BBox3d b3Stm = Stm.GetAllTriaBox() ; + // if ( b3Stm.IsEmpty()) + // return false ; + //// lo ingrandisco per non avere problemi con faccia piana su piani canonici + // b3Stm.Expand( 10 * EPS_SMALL) ; + // double dU1, dU2 ; + // if ( ! IntersLineBox( ptL, vtL, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2)) + // return true ; + // if ( bFinite) { + // dU1 = max( dU1, 0.) ; + // dU2 = min( dU2, dLen) ; + // if ( dU2 - dU1 < EPS_SMALL) + // return true ; + // } + // Point3d ptStart = ptL + dU1 * vtL ; + // double dLenEff = dU2 - dU1 ; + //// cerco i triangoli intersecati dalla linea + // const double BOX_STEP = 10 ; + // int nStep = int( ceil( dLenEff / BOX_STEP)) ; + // Vector3d vtStep = dLenEff / nStep * vtL ; + // INTVECTOR vPrevT ; + // for ( int i = 0 ; i < nStep ; ++ i) { + // BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ; + // INTVECTOR vT ; + // if ( Stm.GetAllTriaOverlapBox( b3Box, vT)) { + // for ( auto nT : vT) { + // if ( find( vPrevT.begin(), vPrevT.end(), nT) == vPrevT.end()) { + // vPrevT.emplace_back( nT) ; + // Triangle3d Tria ; + // Stm.GetTriangle( nT, Tria) ; + // // aggiorno info con intersezione + // UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ; + // } + // } + // } + // } - // ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea - OrderInfoIntersLineSurfTm( vInfo) ; + //// ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea + // OrderInfoIntersLineSurfTm( vInfo) ; - return true ; + // return true ; //////////////////////////////////////////////////////// interlineSurfTm return true ; +} + +//---------------------------------------------------------------------------- +// raffino i punti di intersezione e recupero le rispettive coordinate nello spazio parametrico +bool +RefinePoints( const ISurfTriMesh* pSurfTm ,int nIL, int nT, Point3d& ptI, Point3d& ptI2, Point3d& ptSP, Point3d& ptSP2) { + int nVert[3] ; + pSurfTm->GetTriangle( nT, nVert) ; + double dU0, dV0, dU1, dV1,dU2, dV2 ; + pSurfTm->GetVertexParam( nVert[0], dU0, dV0) ; + pSurfTm->GetVertexParam( nVert[1], dU1, dV1) ; + pSurfTm->GetVertexParam( nVert[2], dU2, dV2) ; + Point3d pt0, pt1, pt2 ; + pSurfTm->GetVertex( nVert[0], pt0) ; + pSurfTm->GetVertex( nVert[1], pt1) ; + pSurfTm->GetVertex( nVert[2], pt2) ; + Eigen::Matrix3d m3x3 ; + //m3x3 << pt0.x, pt1.x, pt2.x, pt0.y, pt1.y, pt2.y, pt0.z, pt1.z, pt2.z ; + m3x3.col(0) << pt0.x, pt0.y , pt0.z ; + m3x3.col(1) << pt1.x, pt1.y , pt1.z ; + m3x3.col(2) << pt2.x, pt2.y , pt2.z ; + Eigen::Vector3d b ( ptI.x, ptI.y, ptI.z) ; + Eigen::Vector3d x = m3x3.fullPivLu().solve(b) ; + } \ No newline at end of file From 0f8012ce61a002ca5e4cb165bda353601c674c5e Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Mon, 12 Feb 2024 12:52:56 +0100 Subject: [PATCH 5/5] EgtGeomKernel : - implementata l'intersezione tra linea e sup bezier. --- EgtGeomKernel.vcxproj.filters | 3 + IntersLineSurfBez.cpp | 293 +++++++++++++++++++++++----------- SurfTriMesh.cpp | 7 - 3 files changed, 199 insertions(+), 104 deletions(-) diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index c24cae1..b22fe9d 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -273,6 +273,9 @@ File di origine\GeoInters + + File di origine\GeoInters + File di origine\GeoCreate diff --git a/IntersLineSurfBez.cpp b/IntersLineSurfBez.cpp index 3637788..34e45fe 100644 --- a/IntersLineSurfBez.cpp +++ b/IntersLineSurfBez.cpp @@ -13,108 +13,21 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include "IntersLineBox.h" #include "/EgtDev/Include/EGkIntersLineTria.h" #include "/EgtDev/Include/EGkIntersLineSurfTm.h" #include "/EgtDev/Include/EGkIntersLineSurfBez.h" #include "/EgtDev/Include/EGkSurfBezier.h" #include "/EgtDev/Extern/Eigen/Dense" +#include "DistPointLine.h" +#include "CurveLine.h" using namespace std ; -//---------------------------------------------------------------------------- -// Intersezione di una linea con una superficie TriMesh -//---------------------------------------------------------------------------- -bool -IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfBezier& SBz, - ILSBIVECTOR& vInfo, bool bFinite) -{ - // verifico linea - Vector3d vtDir = vtL ; - if ( ! vtDir.Normalize( EPS_ZERO)) - return false ; - // verifico superficie - if ( &SBz == nullptr) - return false ; - // verifico parametro di ritorno - if ( &vInfo == nullptr) - return false ; - vInfo.clear() ; - - // trovo le intersezioni con la trimesh ausiliaria - const ISurfTriMesh* pSurfTm = SBz.GetAuxSurf() ; - ILSIVECTOR vInfoTm ; - if ( ! IntersLineSurfTm( ptL, vtL, dLen, *pSurfTm, vInfoTm, bFinite)) - return false ; - - // ricavo le intersezioni con la superficie di Bezier - for ( IntLinStmInfo InfoTm : vInfoTm ) { - // devo raffinare i parametri lungo la curva, l'angolo e i punti di intersezione - double dUU, dUU2, dCos ; - Point3d ptI, ptI2 ; - // devo trovare le intersezioni - Point3d ptSP, ptSP2 ; - RefinePoints( pSurfTm, InfoTm.nILTT, InfoTm.nT, ptI, ptI2,ptSP, ptSP2) ; - IntLinSbzInfo InfoBz( InfoTm.nILTT, dUU, dUU2, InfoTm.nT, dCos, InfoTm.ptI, InfoTm.ptI2, ptSP, ptSP2) ; - vInfo.emplace_back( InfoBz) ; - } - - //////////////////////////////////////////////////////// interlineSurfTm - - - //// limito la linea al box dei triangoli della superficie - // BBox3d b3Stm = Stm.GetAllTriaBox() ; - // if ( b3Stm.IsEmpty()) - // return false ; - //// lo ingrandisco per non avere problemi con faccia piana su piani canonici - // b3Stm.Expand( 10 * EPS_SMALL) ; - // double dU1, dU2 ; - // if ( ! IntersLineBox( ptL, vtL, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2)) - // return true ; - // if ( bFinite) { - // dU1 = max( dU1, 0.) ; - // dU2 = min( dU2, dLen) ; - // if ( dU2 - dU1 < EPS_SMALL) - // return true ; - // } - // Point3d ptStart = ptL + dU1 * vtL ; - // double dLenEff = dU2 - dU1 ; - //// cerco i triangoli intersecati dalla linea - // const double BOX_STEP = 10 ; - // int nStep = int( ceil( dLenEff / BOX_STEP)) ; - // Vector3d vtStep = dLenEff / nStep * vtL ; - // INTVECTOR vPrevT ; - // for ( int i = 0 ; i < nStep ; ++ i) { - // BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ; - // INTVECTOR vT ; - // if ( Stm.GetAllTriaOverlapBox( b3Box, vT)) { - // for ( auto nT : vT) { - // if ( find( vPrevT.begin(), vPrevT.end(), nT) == vPrevT.end()) { - // vPrevT.emplace_back( nT) ; - // Triangle3d Tria ; - // Stm.GetTriangle( nT, Tria) ; - // // aggiorno info con intersezione - // UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ; - // } - // } - // } - // } - - //// ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea - // OrderInfoIntersLineSurfTm( vInfo) ; - - // return true ; - - //////////////////////////////////////////////////////// interlineSurfTm - - - return true ; -} - //---------------------------------------------------------------------------- // raffino i punti di intersezione e recupero le rispettive coordinate nello spazio parametrico bool -RefinePoints( const ISurfTriMesh* pSurfTm ,int nIL, int nT, Point3d& ptI, Point3d& ptI2, Point3d& ptSP, Point3d& ptSP2) { +FindParametricCoord( const ISurfTriMesh* pSurfTm ,int nIL, int nT, const Point3d& ptI, Point3d& ptSP) { + // recupero i dati dei vertici del triangolo che fa intersezione int nVert[3] ; pSurfTm->GetTriangle( nT, nVert) ; double dU0, dV0, dU1, dV1,dU2, dV2 ; @@ -125,12 +38,198 @@ RefinePoints( const ISurfTriMesh* pSurfTm ,int nIL, int nT, Point3d& ptI, Point3 pSurfTm->GetVertex( nVert[0], pt0) ; pSurfTm->GetVertex( nVert[1], pt1) ; pSurfTm->GetVertex( nVert[2], pt2) ; - Eigen::Matrix3d m3x3 ; - //m3x3 << pt0.x, pt1.x, pt2.x, pt0.y, pt1.y, pt2.y, pt0.z, pt1.z, pt2.z ; - m3x3.col(0) << pt0.x, pt0.y , pt0.z ; - m3x3.col(1) << pt1.x, pt1.y , pt1.z ; - m3x3.col(2) << pt2.x, pt2.y , pt2.z ; + // calcolo approssimativamente le coordinate nello spazio parametrico del punto di intersezione + // quindi prima calcolo la composizione lineare tra i vertici del triangolo per ottenere il punto di intersezione + Eigen::Matrix3d mA ; + mA.col(0) << pt0.x, pt0.y , pt0.z ; + mA.col(1) << pt1.x, pt1.y , pt1.z ; + mA.col(2) << pt2.x, pt2.y , pt2.z ; Eigen::Vector3d b ( ptI.x, ptI.y, ptI.z) ; - Eigen::Vector3d x = m3x3.fullPivLu().solve(b) ; + Eigen::Vector3d x = mA.fullPivLu().solve(b) ; + // applico questa composizione alle loro coordinate parametriche + Eigen::Matrix3d mB ; + mB.col(0) << dU0, dV0, 0 ; + mB.col(1) << dU1, dV1, 0 ; + mB.col(2) << dU2, dV2, 0 ; + Eigen::Vector3d ptParam = mB * x ; + ptSP.x = ptParam.x() ; + ptSP.y = ptParam.y() ; + return true ; +} +//---------------------- +bool +RefineIntersNewton( const Point3d& ptL, const Vector3d& vtL, double dLen, bool bFinite, + 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 ; + dpl.GetDist(dDistNew) ; + + int nCount = 0 ; + double dh = EPS_SMALL ; + pSurfBz->GetPointD1D2( ptSP.x, ptSP.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ; + // metodo di newton in pił dimensioni + // vario sia il parametro U che il parametro V e verifico se la distanza dalla retta diminuisce per scostamenti positivi o negativi. + 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) ; + 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) ; + DistPointLine dplNewV( ptIBzNew2, ptL, vtL, dLen, bFinite) ; + dplNewV.GetDist( dDistNew) ; + double dfdV = ( dDistNew - dDistPre) / dh ; + //// opzione 0 + ////scelgo h1 e h2 separatamente e in modo da annullare f(x) + //// opzione 1 + //// valore fisso + //double dr = EPS_SMALL ; + //if ( dDistPre > 1) + // dr = 1 ; + //else if ( dDistPre > 0.1) + // dr = 0.1 ; + //else if ( dDistPre > 0.01) + // dr = 0.01 ; + //// opzione 2 + //// valore direttamente vincolato + //double dr = dDistPre ; + //// opzione 3 + //// valuto la deformazione locale in base allo spostamento del punto sulla bezier // non serve + //double dh1 = Dist( ptIBz, ptIBzNew1) ; + //double dh2 = Dist( ptIBz, ptIBzNew2) ; + // potrei valutare il nuovo spostamento in base all'ultima variazione di dDist + // potrei anche vedere se sto uscendo dal triangolo ( definito nello spazio parametrico) + // 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) ; + DistPointLine dplNew( ptIBz, ptL, vtL, dLen, bFinite) ; + dplNew.GetDist( dDistNew) ; + ++nCount ; + } + + return nCount != 99 ; +} + +////---------------------------------------------------------------------------- +//bool +//RefineIntersBisec( const Point3d& ptL, const Vector3d& vtL, double dLen, bool bFinite, +// const ISurfBezier* pSurfBz, Point3d& ptSP, Point3d& ptIBz) { +// +//} + +//---------------------------------------------------------------------------- +void +UpdateInfoIntersLineSurfBz( const Point3d& ptL, const Vector3d& vtDir, int nILT, int nT, const Point3d& ptSP, const Point3d& ptIBz, double dCos, + const Point3d& ptSP2, const Point3d& ptIBz2, double dCos2, ILSBIVECTOR& vInfo) +{ + if ( nILT == ILTT_IN || nILT == ILTT_EDGE || nILT == ILTT_VERT) { + double dU = ( ptIBz - ptL) * vtDir ; + vInfo.emplace_back( nILT, dU, nT, dCos, ptIBz, ptSP) ; + } + else if ( nILT == ILTT_SEGM || nILT == ILTT_SEGM_ON_EDGE) { + double dU = ( ptIBz - ptL) * vtDir ; + double dU2 = ( ptIBz2 - ptL) * vtDir ; + vInfo.emplace_back( nILT, dU, dU2, nT, dCos2, ptIBz, ptIBz2, ptSP, ptSP2) ; + } +} + +//---------------------------------------------------------------------------- +void +OrderInfoIntersLineSurfBz( ILSBIVECTOR& vInfo) +{ + // se non trovati, esco + if ( vInfo.size() == 0) + return ; + // ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea + sort( vInfo.begin(), vInfo.end(), + []( const IntLinSbzInfo& a, const IntLinSbzInfo& b) + { double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ; + double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ; + return ( dUa < dUb) ; }) ; +} + +//---------------------------------------------------------------------------- +// Intersezione di una linea con una superficie TriMesh +//---------------------------------------------------------------------------- +bool +IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfBezier* pSurfBz, + ILSBIVECTOR& vInfo, bool bFinite) +{ + PtrOwner pCL( CreateCurveLine()) ; + pCL->SetPVL(ptL, vtL, dLen) ; + // verifico linea + Vector3d vtDir = vtL ; + if ( ! vtDir.Normalize( EPS_ZERO)) + return false ; + // verifico superficie + if ( pSurfBz == nullptr) + return false ; + // verifico parametro di ritorno + if ( &vInfo == nullptr) + return false ; + vInfo.clear() ; + + // trovo le intersezioni con la trimesh ausiliaria + const ISurfTriMesh* pSurfTm = pSurfBz->GetAuxSurf() ; + ILSIVECTOR vInfoTm ; + if ( ! IntersLineSurfTm( ptL, vtL, dLen, *pSurfTm, vInfoTm, bFinite)) + return false ; + // ricavo le intersezioni con la superficie di Bezier + for ( IntLinStmInfo InfoTm : vInfoTm ) { + // devo raffinare i parametri lungo la curva, l'angolo e i punti di intersezione + Point3d ptI, ptI2 ; + // devo trovare le intersezioni + Point3d ptSP, ptSP2 ; // coordinate parametriche delle soluzioni + FindParametricCoord( pSurfTm, InfoTm.nILTT, InfoTm.nT, InfoTm.ptI, ptSP) ; + Point3d ptIBz, ptIBz2 ; + if ( ! RefineIntersNewton( ptL, vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz)) { + /////// posso provare anche a rilanciare newton con un punto di partenza diverso oppure con una direzione di avvicinamento diversa/////////////////////////////////// + // per restare nel triangolo mi sposto verso un vertice + int nVert[3] ; + pSurfTm->GetTriangle( InfoTm.nT, nVert) ; + double dU0, dV0 ; + pSurfTm->GetVertexParam( nVert[0], dU0, dV0) ; + ptSP = ptSP + Point3d(dU0, dV0, 0) ; + if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz)) + return false ; + } + Vector3d vtN ; + pSurfBz->GetPointNrmD1D2(ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, 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) + if ( InfoTm.nILTT == ILTT_SEGM || InfoTm.nILTT == ILTT_SEGM_ON_EDGE ) { + FindParametricCoord( pSurfTm, InfoTm.nILTT, InfoTm.nT, InfoTm.ptI2, ptSP2) ; + if ( !RefineIntersNewton(ptL, vtL, dLen, bFinite, pSurfBz, ptSP2, ptIBz2) ) { + int nVert[3] ; + pSurfTm->GetTriangle( InfoTm.nT, nVert) ; + double dU0, dV0 ; + pSurfTm->GetVertexParam( nVert[0], dU0, dV0) ; + ptSP = ptSP + Point3d(dU0, dV0, 0) ; + 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) ; + dCos2 = vtN * vtL ; + } + //IntLinSbzInfo InfoBz( InfoTm.nILTT, dUU, dUU2, InfoTm.nT, dCos, ptIBz, ptIBz2, ptSP, ptSP2) ; + //vInfo.emplace_back( InfoBz) ; + UpdateInfoIntersLineSurfBz( ptL, vtL, InfoTm.nILTT, InfoTm.nT, ptSP, ptIBz, dCos, ptSP2, ptIBz2, dCos2, vInfo) ; + } + + OrderInfoIntersLineSurfBz( vInfo) ; + + //////////////////////////////////////////////////////// interlineSurfTm + //UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ; + // OrderInfoIntersLineSurfTm( vInfo) ; + //////////////////////////////////////////////////////// interlineSurfTm + + + return true ; } \ No newline at end of file diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 19157d9..8bac766 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -505,13 +505,6 @@ SurfTriMesh::GetFirstVertex( Point3d& ptP) const return GetNextVertex( SVT_NULL, ptP) ; } -//---------------------------------------------------------------------------- -int -SurfTriMesh::GetFirstVertexParam( int nId, double& dU, double& dV) const -{ - return GetNextVertexParam( SVT_NULL, dU, dV) ; -} - //---------------------------------------------------------------------------- int SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const