EgtGeomKernel : - piccole correzioni alla

triangolazione delle superfici di Bezier.
This commit is contained in:
Daniele Bariletti
2024-01-23 08:53:53 +01:00
parent 59f5c16c3b
commit 09665eda9f
3 changed files with 100 additions and 50 deletions
+91 -42
View File
@@ -25,6 +25,10 @@
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkCurve.h"
#include "DistPointCrvComposite.h"
///////////per debug
//#include "/EgtDev/Include/EGkStringUtils3d.h"
//#include "/EgtDev/Include/EExDllMain.h"
///////////per debug
//----------------------------------------------------------------------------
Cell::Cell( void)
@@ -239,8 +243,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d
}
}
vLeaves.clear() ;
GetHeightLeaves( -1, vLeaves) ;
m_vnParents = vLeaves ;
}
// controllo se la superficie è chiusa.
// se è chiusa e non ho già fatto split preliminare, splitto sul parametro su cui è chiusa
@@ -318,6 +320,10 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d
}
}
}
// calcolo i parent che ho creato con le eventuali divisioni preliminari
INTVECTOR vLeaves ;
GetHeightLeaves( -1, vLeaves) ;
m_vnParents = vLeaves ;
// calcolo e salvo la lunghezza reale delle curve di bezier di bordo
PtrOwner<CurveComposite> pCrvV0( m_pSrfBz->GetCurveOnU( 0)) ;
@@ -1428,7 +1434,12 @@ Tree::GetPolygons( std::vector<POLYLINEVECTOR>& vPolygons) {
// scorro sulle celle e costruisco i poligoni
int nCells = (int)vPolygonsBasic.size() ;
for ( int i = 0 ; i < nCells ; ++i) {
///////////per debug
//std::string sOut = std::to_string( i) ;
//LOG_ERROR( GetEGkLogger(), sOut.c_str()) ;
///////////per debug
//
// costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps
int nId = m_vnLeaves[i] ;
if ( m_mTree[nId].m_nFlag == 4) {
@@ -1638,7 +1649,7 @@ Tree::ResetTree( void)
//----------------------------------------------------------------------------
INTVECTOR
Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const
Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim, bool bRecurs) const
{
INTVECTOR nCells ;
int nId = -1 ;
@@ -1679,26 +1690,31 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const
}
nCells.push_back( nId) ;
// se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta
Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ;
Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ;
if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL ||
abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL)
{
Point3d ptToAssignPlus ;
double dParam ;
Vector3d vDir ;
clTrim.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ;
clTrim.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptToAssignPlus, vDir) ;
if ( abs( vDir.x) > 1 - EPS_SMALL || abs( vDir.y) > 1 - EPS_SMALL) {
vDir.Rotate( Z_AX, -90) ;
ptToAssignPlus = ptToAssignPlus + vDir * 2 * EPS_SMALL ;
}
nCells = FindCell( ptToAssignPlus, clTrim) ;
if ( nCells.empty()) {
ptToAssignPlus = ptToAssignPlus - 4 * vDir * EPS_SMALL ;
nCells = FindCell( ptToAssignPlus, clTrim) ;
if ( ! bRecurs) {
// se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta
Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ;
Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ;
if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL ||
abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL)
{
Point3d ptToAssignPlus ;
double dParam ;
Vector3d vtDir ;
clTrim.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ;
clTrim.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptToAssignPlus, vtDir) ;
if ( abs( vtDir.x) > 1 - EPS_SMALL || abs( vtDir.y) > 1 - EPS_SMALL) {
vtDir.Rotate( Z_AX, -90) ;
ptToAssignPlus = ptToAssignPlus + vtDir * 2 * EPS_SMALL ;
}
nCells = FindCell( ptToAssignPlus, clTrim, true) ;
if ( nCells.empty()) {
ptToAssignPlus = ptToAssignPlus - 2 * vtDir * EPS_SMALL ;
vtDir.Rotate( Z_AX, 90) ;
ptToAssignPlus = ptToAssignPlus + 10 * vtDir * EPS_SMALL ;
nCells = FindCell( ptToAssignPlus, clTrim, true) ;
if ( nCells.empty())
nCells.push_back( nId) ;
}
}
}
return nCells ;
@@ -1711,22 +1727,47 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
// se non trova nulla restituisce un vettore vuoto
// restituisce sempre solo una cella
// la CurveLine è il segmento di trim su cui giace ptToAssign
Point3d ptIntersPlus ;
double dParam ;
Vector3d vDir ;
cl.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ;
// mi sposto appena più avanti di ptToAssign
cl.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptIntersPlus, vDir) ;
// questo punto va trovato con precisione, perché se seleziono la cella sbagliata si incasina tutto
INTVECTOR nCells ;
int nId = -1 ;
for ( int nCell : vCells) {
if ( ptIntersPlus.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptIntersPlus.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO &&
ptIntersPlus.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptIntersPlus.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) {
if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x &&
ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y) {
nId = nCell ;
nCells.push_back( nId) ;
}
}
// se non ho trovato nulla vuol dire che sono su un vertice o su un lato
if ( (int)nCells.size() == 0 ) {
for ( int nCell : vCells) {
if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO &&
ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) {
nId = nCell ;
nCells.push_back( nId) ;
}
}
if ( (int)nCells.size() == 1)
return nCells ;
// sono su vertice o un lato, quindi avanzo con il parametro lungo la curva
else if ( (int)nCells.size() >= 1 ) {
// la CurveLine è il segmento di trim su cui giace ptToAssign
Point3d ptIntersPlus ;
double dParam ;
Vector3d vDir ;
cl.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ;
cl.GetStartDir( vDir) ;
// mi sposto appena più avanti di ptToAssign
// se la curva è orientata come l'asse x o y mi sto muovendo su un lato e sarò ancora sul lato, quindi dovrei ruotare il vettore prima di spostarmi
if ( abs( vDir.x) >= 1 - EPS_SMALL || abs( vDir.y) >= 1 - EPS_SMALL)
vDir.Rotate( Z_AX, -45) ;
ptIntersPlus = ptToAssign + vDir * EPS_SMALL ;
nCells = FindCell( ptIntersPlus, cl, vCells) ;
}
// se vuoto allora il punto non è in nessuna delle celle passate in input
else
return nCells ;
}
return nCells ;
}
@@ -1842,10 +1883,12 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
Point3d ptLast = m_mTree[nId].m_vInters.back().vpt.back() ;
//sistemo l'ingresso della prima cella
int nEdge ;
OnWhichEdge( nFirstCell, ptFirst, nEdge) ;
if ( ! OnWhichEdge( nFirstCell, ptFirst, nEdge))
return false ;
m_mTree[nFirstCell].m_vInters[nPass].nIn = nEdge ;
// sistemo l'uscita dell'ultima cella
OnWhichEdge( nId, ptLast, nEdge) ;
if ( ! OnWhichEdge( nId, ptLast, nEdge))
return false ;
m_mTree[nId].m_vInters.back().nOut = nEdge ;
// sistemo il flag dell'ultima cella
if ( m_mTree[nId].m_nFlag == -1)
@@ -2125,11 +2168,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
if ( ! clEdge2.IsValid())
return false ;
}
else if ( aInfo.bOverlap && ! bFirstInters) {
ptInters = aInfo.IciA[1].ptI ;
bIntersFound = true ;
}
if ( clEdge2.IsValid() && ! bIntersFound){
//else if ( aInfo.bOverlap && ! bFirstInters) {
// ptInters = aInfo.IciA[1].ptI ;
// bIntersFound = true ;
//}
else
bIntersOn1Found = true ;
if ( clEdge2.IsValid() && ! bIntersOn1Found){
IntersLineLine illExit2( clTrim, clEdge2, true) ;
// verifico su quale dei due lati ho l'intersezione
if ( ! illExit2.GetIntCrvCrvInfo( aInfo2)){
@@ -2152,8 +2197,12 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
ptInters = aInfo2.IciA[0].ptI ;
}
}
else
ptInters = aInfo.IciA[0].ptI ; // qui devo mettere il controllo su prima o seconda intersezione?
else {
if ( aInfo.bOverlap && ! bFirstInters)
ptInters = aInfo.IciA[1].ptI ;
else
ptInters = aInfo.IciA[0].ptI ;
}
}
if ( ! bIntersOn2Found)
OnWhichEdge( nId, ptInters, nEdge) ;