EgtGeomKernel 2.4d1 :

- in OffsetCurve aggiunta funzione che restituisce punto di offset nel caso in cui non siano calcolabili curve
- correzione offset Voronoi nel caso di arco con raggio minore di EPS.
This commit is contained in:
SaraP
2025-04-08 08:37:20 +02:00
parent b7a4f0bff3
commit fef361bea6
4 changed files with 130 additions and 10 deletions
BIN
View File
Binary file not shown.
+39
View File
@@ -60,6 +60,8 @@ OffsetCurve::Reset( void)
}
}
m_CrvLst.clear() ;
m_pt = P_INVALID ;
m_vt = V_INVALID ;
return true ;
}
@@ -704,6 +706,18 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
double dCorr = ( dDist > 0 ? - VRONI_OFFS_TOL : VRONI_OFFS_TOL) ;
voronoiObj->CalcOffset( vOffs, dDist + dCorr, nType) ;
}
// se ancora vuoto calcolo i punti speciali di offset ( punti e direzioni sui bisettore alla distanza richiesta)
if ( vOffs.empty()) {
PNTVECTVECTOR vPntOffs ;
voronoiObj->CalcSpecialPointOffset( vPntOffs, dDist) ;
// NB al momento vengono gestiti solo i casi in cui vi è un unico punto di offset. Se si ottengono più punti di offset
// ( e.g. alcune curve aperte) non se ne restiusce nessuno. Da estendere, se necessario, individuando i punti dal lato
// di offset richiesto
if ( vPntOffs.size() == 1) {
m_pt = vPntOffs[0].first ;
m_vt = vPntOffs[0].second ;
}
}
}
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++)
@@ -733,10 +747,21 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
pCrv->Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
pCrv->ToGlob( frCopy) ;
}
if ( m_pt.IsValid()) {
m_pt.Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
m_pt.ToGlob( frCopy) ;
m_vt.Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
m_vt.ToGlob( frCopy) ;
}
}
else if ( bNeedRef) {
for ( auto pCrv : m_CrvLst)
pCrv->ToGlob( frCopy) ;
if ( m_pt.IsValid()) {
m_pt.ToGlob( frCopy) ;
m_vt.ToGlob( frCopy) ;
}
}
// assegno estrusione e spessore come curva originale e unisco parti allineate
@@ -814,6 +839,20 @@ OffsetCurve::GetShorterCurve( void)
return pCrv ;
}
//----------------------------------------------------------------------------
bool
OffsetCurve::GetPointOffset( Point3d& pt, Vector3d& vt)
{
// verifico se valori validi da restituire
if ( ! m_pt.IsValid() || ! m_vt.IsValid())
return false ;
pt = m_pt ;
vt = m_vt ;
return true ;
}
//----------------------------------------------------------------------------
bool
PreviousIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bool bClosed)
+90 -10
View File
@@ -574,7 +574,7 @@ Voronoi::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide)
if ( m_vroni->IsWMATEdge( i)) {
PtrOwner<ICurve> pCrv( GetBisectorCurve( i)) ;
if ( ! IsNull( pCrv) && pCrv->IsValid())
vCrvs.emplace_back( Release( pCrv)) ;
vCrvs.emplace_back( Release( pCrv)) ;
}
}
@@ -594,7 +594,7 @@ bool
Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType)
{
vOffs.clear() ;
if ( ! IsValid())
return false ;
@@ -767,6 +767,76 @@ Voronoi::CalcSingleCurvesOffset( ICURVEPOVECTOR& vOffs, double dOffs)
return true ;
}
//----------------------------------------------------------------------------
bool
Voronoi::CalcSpecialPointOffset( PNTVECTVECTOR& vResult, double dOffs)
{
// calcola i punti e le tangenti sui bisettori del medial axis in corrispondenza del valore di offset richiesto
vResult.clear() ;
if ( abs( dOffs) < EPS_SMALL)
return true ;
if ( ! IsValid())
return false ;
try {
// verifico se necessario ricalcolo Voronoi
UpdateVoronoi( dOffs) ;
// indivudio lato medial axis per curve chiuse ( suppongo di chiamare la funzione dalla singola curva, quindi vale controllare
// la chiusura solo sulla prima curva. Eventualmente da estendere)
bool bLeft = true, bRight = true ;
if ( m_vpCrvs[0]->IsClosed()) {
bLeft = dOffs < 0 ;
bRight = ! bLeft ;
}
// calcolo medial axis
m_vroni->apiComputeWMAT( false, 0.0, 0.0, false, bLeft, bRight) ;
for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) {
// verifico se il lato appartiene al medial axis
if ( m_vroni->IsWMATEdge( i)) {
// verifico se coinvolto dall'offset
double dParS, dParE ;
m_vroni->GetBisectorParams( i, dParS, dParE) ;
if ( dParS > dParE)
swap( dParS, dParE) ;
if ( abs( dOffs) < dParS || abs( dOffs) > dParE)
continue ;
// calcolo il punto sul bisettore in corrispondenza dell'offset
Point3d pt ;
m_vroni->GetBisectorPointAtParam( i, abs( dOffs), pt.v) ;
// calcolo il vettore tangente
PtrOwner<ICurve> pCrv( GetBisectorCurve( i)) ;
if ( IsNull( pCrv))
return false ;
double dPar ;
Point3d ptTemp ;
Vector3d vtDir ;
if ( ! pCrv->GetParamAtPoint( pt, dPar, 100 * EPS_SMALL) || ! pCrv->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptTemp, &vtDir))
return false ;
vtDir.Normalize() ;
vResult.emplace_back( pt, vtDir) ;
}
}
// libero la memoria di vroni utilizzata per calcolare bisettori
m_vroni->apiFreeBisectorBuffer() ;
}
catch (...) {
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bool bSquareMids)
@@ -886,14 +956,24 @@ Voronoi::CalcVroniOffset( ICRVCOMPOPLIST& OffsList, double dOffs)
}
else {
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
pArc->SetC2P( ptC, ptS, ptE) ;
// verifico orientamento
double dAng = pArc->GetAngCenter() ;
if ( ( nType == CCW && dAng < - EPS_ANG_SMALL) || ( nType == CW && dAng > EPS_ANG_SMALL))
pArc->ToExplementary() ;
// aggiungo alla composita
if ( ! pCrvOffs->AddCurve( Release( pArc)))
return false ;
if ( ! pArc->SetC2P( ptC, ptS, ptE)) {
// se raggio minore di EPS_SMALL approssimo con linea
if ( AreSamePointApprox( ptC, ptS)) {
if ( ! pCrvOffs->AddLine( ptE))
return false ;
}
else
return false ;
}
else {
// verifico orientamento
double dAng = pArc->GetAngCenter() ;
if ( ( nType == CCW && dAng < - EPS_ANG_SMALL) || ( nType == CW && dAng > EPS_ANG_SMALL))
pArc->ToExplementary() ;
// aggiungo alla composita
if ( ! pCrvOffs->AddCurve( Release( pArc)))
return false ;
}
}
// setto come info la sottocurva da cui si è generata
+1
View File
@@ -56,6 +56,7 @@ class Voronoi
bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = VORONOI_STD_BOUND) ;
bool CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType) ;
bool CalcSingleCurvesOffset( ICURVEPOVECTOR& vOffs, double dOffs) ;
bool CalcSpecialPointOffset( PNTVECTVECTOR& vResult, double dOffs) ;
bool CalcFatCurve( ICURVEPOVECTOR& vOffs, double dOffs, bool bSquareEnds, bool bSquareMids) ;
bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) ;
bool CalcLimitOffset( int nCrv, bool bLeft, double& dOffs) ;