From dabbd3eae5670a5e4feaacd1843a12299b0f3c0c Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 15 May 2019 19:01:14 +0000 Subject: [PATCH] EgtGeomKernel : - aggiunta a PolyLine IsFlat che restituisce direttamente un piano, se esiste - a GetSurfTriMeshByScrewing aggiunto parametro per tappare gli estremi - migliorata GetSurfTriMeshSwept. --- GdbExecutor.cpp | 2 +- PolyLine.cpp | 28 +++++++++++++++++++++++++ StmFromCurves.cpp | 53 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 66 insertions(+), 17 deletions(-) diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 549bb5f..f07f073 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -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 diff --git a/PolyLine.cpp b/PolyLine.cpp index 8e102b5..508764a 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -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 diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp index d11f146..baca130 100644 --- a/StmFromCurves.cpp +++ b/StmFromCurves.cpp @@ -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 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 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 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 pSTM( CreateSurfTriMesh()) ; @@ -347,7 +370,7 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d PtrOwner 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 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 pSci( CreateSurfTriMesh()) ;