EgtGeomKernel :

- aggiunta a PolyLine IsFlat che restituisce direttamente un piano, se esiste
- a GetSurfTriMeshByScrewing aggiunto parametro per tappare gli estremi
- migliorata GetSurfTriMeshSwept.
This commit is contained in:
Dario Sassi
2019-05-15 19:01:14 +00:00
parent 5b707f1799
commit dabbd3eae5
3 changed files with 66 additions and 17 deletions
+1 -1
View File
@@ -2483,7 +2483,7 @@ GdbExecutor::SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams)
if ( ! FromString( vsParams[5], dAngRotDeg))
return false ;
// calcolo la superficie
ISurfTriMesh* pSTM = GetSurfTriMeshByScrewing( CrvLoc, ptAx, vtAx, dAngRotDeg, dMove, dLinTol) ;
ISurfTriMesh* pSTM = GetSurfTriMeshByScrewing( CrvLoc, ptAx, vtAx, dAngRotDeg, dMove, false, dLinTol) ;
if ( pSTM == nullptr)
return false ;
// inserisco la superficie trimesh nel DB
+28
View File
@@ -558,6 +558,34 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
return true ;
}
//----------------------------------------------------------------------------
bool
PolyLine::IsFlat( Plane3d& plPlane, double dToler) const
{
// verifico non sia vuota
if ( GetPointNbr() == 0) {
plPlane.Reset() ;
return false ;
}
// recupero dati sulla planarità della polilinea
int nRank ;
Point3d ptCen ;
Vector3d vtDir ;
bool bFlat = IsFlat( nRank, ptCen, vtDir, dToler) ;
// imposto il piano a seconda della dimensionalità
switch ( nRank) {
case 0 : // punto
plPlane.Set( ptCen, Z_AX) ;
case 1 : // linea
plPlane.Set( ptCen, FromUprightOrtho( vtDir)) ;
break ;
default : // piana o 3d
plPlane.Set( ptCen, vtDir) ;
break ;
}
return bFlat ;
}
//----------------------------------------------------------------------------
bool
PolyLine::IsClosedAndFlat( Plane3d& plPlane, double& dArea, double dToler) const
+37 -16
View File
@@ -258,7 +258,7 @@ GetSurfTriMeshByRevolve( const ICurve* pCurve, const Point3d& ptAx, const Vector
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
double dAngRotDeg, double dMove, double dLinTol)
double dAngRotDeg, double dMove, bool bCapEnds, double dLinTol)
{
// verifica parametri
if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
@@ -284,6 +284,33 @@ GetSurfTriMeshByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vecto
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByScrewing( PL, ptAx, vtAx, dAngRotDeg, dStepRotDeg, dMove))
return nullptr ;
// se richiesti caps
if ( bCapEnds) {
// determino se la sezione è chiusa e piatta
Plane3d plPlane ; double dArea ;
bool bSectClosedFlat = PL.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ;
// determino non sia una semplice rivoluzione
bool bRevolved = ( abs( abs( dAngRotDeg) - ANG_FULL) < EPS_ANG_SMALL && abs( dMove) < EPS_SMALL) ;
// se sezione chiusa e piatta e non rivoluzione, posso aggiungere i tappi
if ( bSectClosedFlat && ! bRevolved) {
// aggiungo il cap sull'inizio
PtrOwner<ISurfTriMesh> pSci( CreateSurfTriMesh()) ;
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
return nullptr ;
pSTM->DoSewing( *pSci) ;
// aggiungo il cap sulla fine
Vector3d vtMove = vtAx ;
vtMove.Normalize() ;
vtMove *= dMove ;
PL.Translate( vtMove) ;
PL.Rotate( ptAx, vtAx, dAngRotDeg) ;
PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
return nullptr ;
pSce->Invert() ;
pSTM->DoSewing( *pSce) ;
}
}
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
double dVol ;
if ( pSTM->GetVolume( dVol) && dVol < 0)
@@ -301,16 +328,12 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
// verifica parametri
if ( pSect == nullptr || pGuide == nullptr)
return nullptr ;
// verifico che la sezione sia piana
Plane3d plSect ;
if ( ! pSect->IsFlat( plSect, 10 * EPS_SMALL))
return nullptr ;
// determino se la sezione è chiusa
bool bSectClosed = pSect->IsClosed() ;
// calcolo la polilinea che approssima la sezione
PolyLine PL ;
if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return nullptr ;
// determino se la sezione è chiusa
bool bSectClosed = PL.IsClosed() ;
// verifico che la linea guida sia piana
Plane3d plGuide ;
if ( ! pGuide->IsFlat( plGuide, 10 * EPS_SMALL))
@@ -326,8 +349,8 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
Vector3d vtExtr = Z_AX ;
pGuide->GetExtrusion( vtExtr) ;
frStart.Set( ptStart, -vtStart, vtStart ^ vtExtr) ;
// porto la sezione in questo riferimento
if ( ! PL.ToLoc( frStart))
// porto la sezione in questo riferimento e ve la appiattisco
if ( ! PL.ToLoc( frStart) || ! PL.Flatten())
return nullptr ;
// calcolo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
@@ -347,7 +370,7 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
PtrOwner<ICurve> pCurrCrv( OffsCrv.GetLongerCurve()) ;
if ( IsNull( pCurrCrv))
return nullptr ;
pCurrCrv->Translate( ptP.y * frStart.VersY() + ptP.z * frStart.VersZ()) ;
pCurrCrv->Translate( ptP.y * frStart.VersY()) ;
// se esiste la curva precedente, costruisco la rigata (di tipo minima distanza)
if ( ! IsNull( pPrevCrv)) {
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
@@ -362,16 +385,14 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
}
// se richiesti caps e sezione chiusa e guida aperta
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
// verifico che le due estremità siano piatte
// verifico che le due estremità siano chiuse e piatte
POLYLINEVECTOR vPL ;
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
return nullptr ;
int nRank ;
Point3d ptCen ;
Vector3d vtDir ;
if ( ! vPL[0].IsFlat( nRank, ptCen, vtDir, 100 * EPS_SMALL))
Plane3d plEnds ; double dArea ;
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
return nullptr ;
if ( ! vPL[1].IsFlat( nRank, ptCen, vtDir, 100 * EPS_SMALL))
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
return nullptr ;
// aggiungo il cap sull'inizio
PtrOwner<ISurfTriMesh> pSci( CreateSurfTriMesh()) ;