Compare commits

...

2 Commits

Author SHA1 Message Date
SaraP 91a9adaea4 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.
2025-04-08 08:37:20 +02:00
Dario Sassi b7a4f0bff3 EgtGeomKernel :
- a SurfTriMesh aggiunto metodo CreateByPolygonWithHoles.
2025-03-28 20:17:50 +01:00
7 changed files with 146 additions and 16 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)
+2 -4
View File
@@ -577,10 +577,8 @@ SurfFlatRegionByContours::GetUnusedCurveTempProps( INTVECTOR& vId)
bool
CalcRegionPolyLines( const POLYLINEVECTOR& vPL, Vector3d& vtN, INTMATRIX& vnPLIndMat, BOOLVECTOR& vbInvert)
{
// matrice di interi : ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
// successive i loop interni
//INTMATRIX vnPLIndMat ;
// vettore di bool : riferito al vettore originale delle polyline, riporta true se la polyline è stata invertita
// vnPLIndMat : ogni riga corrisponde ad un chunk, in posizione 0 c'è il loop esterno e nelle successive i loop interni
// vbInvert : riferito al vettore delle polyline, riporta true se la polyline è stata invertita
// ricavo versore normale
Plane3d plPlane ; double dArea ;
+11
View File
@@ -2091,6 +2091,17 @@ SurfTriMesh::CreateByFlatContour( const PolyLine& PL)
return AdjustTopology() ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::CreateByPolygonWithHoles( const POLYLINEVECTOR& vPL)
{
INTMATRIX vnPLIndMat ;
vnPLIndMat.push_back( { 0}) ;
for ( int i = 1 ; i < int( vPL.size()) ; ++ i)
vnPLIndMat[0].push_back( i) ;
return CreateByRegion( vPL, vnPLIndMat) ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::CreateByRegion( const POLYLINEVECTOR& vPL, const INTMATRIX& vnPLIndMat)
+3 -2
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2023
// EgalTech 2014-2025
//----------------------------------------------------------------------------
// File : SurfTriMesh.h Data : 09.12.23 Versione : 2.5l2
// File : SurfTriMesh.h Data : 28.03.25 Versione : 2.7c4
// Contenuto : Dichiarazione della classe Superficie TriMesh.
//
//
@@ -251,6 +251,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
bool RemoveTriangle( int nId) override ;
bool AdjustTopology( void) override ;
bool CreateByFlatContour( const PolyLine& PL) override ;
bool CreateByPolygonWithHoles( const POLYLINEVECTOR& vPL) override ;
bool CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) override ;
bool CreateByPointCurve( const Point3d& ptP, const PolyLine& PL) override ;
bool CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nRuledType) override ;
+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) ;