From 2dd5001940cad2c4e988294cc31853357f34f4f7 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 2 Feb 2015 08:06:49 +0000 Subject: [PATCH] EgtGeomKernel 1.6b1 : - aggiunte funzioni di costruzione superfici Stm da curve - aggiunta funzione di svuota gruppo - aggiunta funzione di inverti polilinea. --- EgtGeomKernel.rc | Bin 11710 -> 11710 bytes EgtGeomKernel.vcxproj | 2 + EgtGeomKernel.vcxproj.filters | 6 + GeomDB.cpp | 32 ++++++ GeomDB.h | 2 + PolyLine.cpp | 21 ++++ StmFromCurves.cpp | 211 ++++++++++++++++++++++++++++++++++ StmFromTriangleSoup.cpp | 2 +- SurfTriMesh.cpp | 2 +- Triangulate.cpp | 2 +- 10 files changed, 277 insertions(+), 3 deletions(-) create mode 100644 StmFromCurves.cpp diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 8427a4c3fe9e9be952949a6200e94085584bc4d1..b6410ac66ecb835a187f86279ae0f86be81d052f 100644 GIT binary patch delta 118 zcmdlNy)SyhH#Sxy1|0^&&A-{?nVFLq3@0mc>u&bq>S2M3-{!MM7I$OZ+#~G9j8n2h Q8ZL=uq6g#VEaea`08%6!@&Et; delta 118 zcmdlNy)SyhH#Sy71|0^|&A-{?nVAzAOeZUH>u&bq>S2M3-{!MM7I$OZ+#~G9j8n2h Q8ZL=uq6g#VEaea`09V!?3IG5A diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 7e39517..c484bd8 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -314,6 +314,7 @@ copy $(TargetPath) \EgtProg\Dll64 Create Create + @@ -366,6 +367,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 2afba14..404c1f4 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -249,6 +249,9 @@ File di origine\Geo + + File di origine\GeoCreate + @@ -587,6 +590,9 @@ File di intestazione\Include + + File di intestazione\Include + diff --git a/GeomDB.cpp b/GeomDB.cpp index 20c5b18..dd5cddc 100644 --- a/GeomDB.cpp +++ b/GeomDB.cpp @@ -965,6 +965,38 @@ GeomDB::Erase( GdbObj* pGdbObj) return true ; } +//---------------------------------------------------------------------------- +bool +GeomDB::EmptyGroup( int nId) +{ + // escludo Id non validi + if ( nId < GDB_ID_ROOT) + return false ; + + // recupero l'oggetto + GdbObj* pGdbObj ; + pGdbObj = m_IdManager.FindObj( nId) ; + if ( pGdbObj == nullptr) + return false ; + + return EmptyGroup( pGdbObj) ; +} + +//---------------------------------------------------------------------------- +bool +GeomDB::EmptyGroup( GdbObj* pGdbObj) +{ + // deve essere valido e non il gruppo radice + if ( pGdbObj == nullptr || pGdbObj == &m_GrpRadix) + return false ; + // deve essere un gruppo + GdbGroup* pGrp = ::GetGdbGroup( pGdbObj) ; + if ( pGrp == nullptr) + return false ; + // lo svuoto + return pGrp->Clear() ; +} + //---------------------------------------------------------------------------- bool GeomDB::Translate( int nId, const Vector3d& vtMove) diff --git a/GeomDB.h b/GeomDB.h index 5955b4c..82fbb91 100644 --- a/GeomDB.h +++ b/GeomDB.h @@ -74,6 +74,7 @@ class GeomDB : public IGeomDB { return Relocate( nId, nRefId, nSonBeforeAfter, true) ; } virtual bool ChangeId( int nId, int nNewId) ; virtual bool Erase( int nId) ; + virtual bool EmptyGroup( int nId) ; virtual bool Translate( int nId, const Vector3d& vtMove) ; virtual bool TranslateGlob( int nId, const Vector3d& vtMove) ; virtual bool TranslateGroup( int nId, const Vector3d& vtMove) ; @@ -198,6 +199,7 @@ class GeomDB : public IGeomDB int Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob) ; bool Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob) ; bool Erase( GdbObj* pGObj) ; + bool EmptyGroup( GdbObj* pGdbObj) ; bool LoadHeader( NgeReader& ngeIn, bool bSave) ; bool LoadOneObj( NgeReader& ngeIn, int nGroupId, int nBaseGdbId, const INTVECTOR& vBaseMatId, bool& bEnd) ; bool SaveHeader( NgeWriter& ngeOut) const ; diff --git a/PolyLine.cpp b/PolyLine.cpp index c96d02f..d329322 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -654,5 +654,26 @@ PolyLine::AdjustForMaxSegmentLen( double& dMaxLen) return false ; } + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyLine::Invert( bool bInvertU) +{ + // verifico non sia vuota + if ( m_lUPoints.empty()) + return true ; + // inverto la lista + m_lUPoints.reverse() ; + // se richiesto, inverto anche il parametro U + if ( bInvertU) { + // recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione + double dUfin = m_lUPoints.front().second ; + // ciclo su tutti gli elementi + for ( PNTULIST::iterator iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) { + iter->second = dUfin - iter->second ; + } + } return true ; } \ No newline at end of file diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp new file mode 100644 index 0000000..0504c5e --- /dev/null +++ b/StmFromCurves.cpp @@ -0,0 +1,211 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2015 +//---------------------------------------------------------------------------- +// File : StmFromCurves.cpp Data : 01.02.15 Versione : 1.6b1 +// Contenuto : Implementazione di funzioni per creazione di superfici Stm +// a partire da curve, con diversi metodi. +// +// +// Modifiche : 01.02.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "GeoConst.h" +#include "/EgtDev/Include/EGkStmFromCurves.h" +#include "/EgtDev/Include/EgtPointerOwner.h" +#include + +using namespace std ; + +//------------------------------------------------------------------------------- +ISurfTriMesh* +GetSurfTriMeshByContour( const ICurve& Curve, double dLinTol) +{ + // verifica parametri + if ( &Curve == nullptr) + return nullptr ; + // calcolo la polilinea che approssima la curva + PolyLine PL ; + if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + return nullptr ; + // creo e setto la superficie trimesh + PtrOwner pSTM( CreateSurfTriMesh()) ; + if ( IsNull( pSTM) || ! pSTM->CreateByFlatContour( PL)) + return nullptr ; + // restituisco la superficie + return Release( pSTM) ; +} + +//------------------------------------------------------------------------------- +ISurfTriMesh* +GetSurfTriMeshByExtrusion( const ICurve& Curve, const Vector3d& vtExtr, + bool bCapEnds, double dLinTol) +{ + // verifica parametri + if ( &Curve == nullptr || &vtExtr == nullptr) + return nullptr ; + // calcolo la polilinea che approssima la curva + PolyLine PL ; + if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + return nullptr ; + // se richiesta chiusura agli estremi + bool bDoCapEnds = false ; + if ( bCapEnds) { + // verifico che la curva sia chiusa e piatta + Plane3d plPlane ; + double dArea ; + if ( PL.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL)) { + // componente dell'estrusione perpendicolare al piano della curva + double dOrthoExtr = plPlane.vtN * vtExtr ; + if ( ( fabs( dOrthoExtr) > EPS_SMALL)) { + bDoCapEnds = true ; + if ( dOrthoExtr < 0) + PL.Invert() ; + } + } + } + // creo e setto la superficie trimesh + PtrOwner pSTM( CreateSurfTriMesh()) ; + if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr)) + return nullptr ; + // se da fare, metto i tappi sulle estremità + if ( bDoCapEnds) { + // creo la prima superficie di estremità + PtrOwner pSTM1( CreateSurfTriMesh()) ; + if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL)) + return nullptr ; + // la copio + PtrOwner pSTM2( GetSurfTriMesh( pSTM1->Clone())) ; + if ( IsNull( pSTM2)) + return nullptr ; + // inverto la prima superficie + pSTM1->Invert() ; + // traslo la seconda + pSTM2->Translate( vtExtr) ; + // le unisco alla superficie del fianco + if ( ! pSTM->DoSewing( *pSTM1) || ! pSTM->DoSewing( *pSTM2)) + return nullptr ; + } + // restituisco la superficie + return Release( pSTM) ; +} + +//------------------------------------------------------------------------------- +ISurfTriMesh* +GetSurfTriMeshByRevolve( const ICurve& Curve, const Point3d& ptAx, const Vector3d& vtAx, + bool bCapEnds, double dLinTol) +{ + // verifica parametri + if ( &Curve == nullptr || &ptAx == nullptr || &vtAx == nullptr) + return nullptr ; + // limite minimo su tolleranza + dLinTol = max( dLinTol, EPS_SMALL) ; + // calcolo la polilinea che approssima la curva + PolyLine PL ; + if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + return nullptr ; + // calcolo lo step di rotazione + double dMaxRad = 0 ; + if ( ! PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) || dMaxRad < EPS_SMALL) + return nullptr ; + double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ; + // se richiesta chiusura degli estremi + if ( bCapEnds && ! PL.IsClosed()) { + Vector3d vtAxN = vtAx ; + vtAxN.Normalize() ; + double dPosIni, dPosFin ; + Point3d ptP ; + // proietto l'ultimo punto sull'asse di rotazione + if ( PL.GetLastPoint( ptP)) { + dPosFin = ( ptP - ptAx) * vtAxN ; + Point3d ptPOnAx = ptAx + dPosFin * vtAxN ; + // se non giace sull'asse, aggiungo il punto proiettato + if ( ! AreSamePointApprox( ptP, ptPOnAx)) { + double dU ; + PL.GetLastU( dU) ; + PL.AddUPoint( ( dU + 1), ptPOnAx) ; + } + } + // inverto la polilinea + PL.Invert() ; + // proietto l'ultimo punto (era il primo) sull'asse di rotazione + if ( PL.GetLastPoint( ptP)) { + dPosIni = ( ptP - ptAx) * vtAxN ; + Point3d ptPOnAx = ptAx + dPosIni * vtAxN ; + // se non giace sull'asse, aggiungo il punto proiettato + if ( ! AreSamePointApprox( ptP, ptPOnAx)) { + double dU ; + PL.GetLastU( dU) ; + PL.AddUPoint( ( dU + 1), ptPOnAx) ; + } + } + // decido se reinvertire la polilinea + if ( dPosFin > dPosIni) + PL.Invert() ; + } + // creo e setto la superficie trimesh + PtrOwner pSTM( CreateSurfTriMesh()) ; + if ( IsNull( pSTM) || ! pSTM->CreateByScrewing( PL, ptAx, vtAx, ANG_FULL, dStepRotDeg, 0)) + return nullptr ; + // restituisco la superficie + return Release( pSTM) ; +} + +//------------------------------------------------------------------------------- +ISurfTriMesh* +GetSurfTriMeshByScrewing( const ICurve& Curve, const Point3d& ptAx, const Vector3d& vtAx, + double dAngRotDeg, double dMove, double dLinTol) +{ + // verifica parametri + if ( &Curve == nullptr || &ptAx == nullptr || &vtAx == nullptr) + return nullptr ; + // limite minimo su tolleranza + dLinTol = max( dLinTol, EPS_SMALL) ; + // calcolo la polilinea che approssima la curva + PolyLine PL ; + if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + return nullptr ; + // calcolo lo step di rotazione + double dMaxRad = 0 ; + if ( ! PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) || dMaxRad < EPS_SMALL) + return nullptr ; + double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ; + // se superficie rototraslata, necessari limiti sulla lunghezza dei segmenti + if ( fabs( dAngRotDeg) > EPS_ANG_SMALL && fabs( dMove) > EPS_SMALL){ + double dLenMax = 2.5 * fabs( dMove * dStepRotDeg / dAngRotDeg) ; + if ( ! PL.AdjustForMaxSegmentLen( dLenMax)) + return nullptr ; + } + // creo e setto la superficie trimesh + PtrOwner pSTM( CreateSurfTriMesh()) ; + if ( IsNull( pSTM) || ! pSTM->CreateByScrewing( PL, ptAx, vtAx, dAngRotDeg, dStepRotDeg, dMove)) + return nullptr ; + // restituisco la superficie + return Release( pSTM) ; +} + +//------------------------------------------------------------------------------- +ISurfTriMesh* +GetSurfTriMeshRuled( const ICurve& Curve1, const ICurve& Curve2, double dLinTol) +{ + // verifica parametri + if ( &Curve1 == nullptr || &Curve2 == nullptr) + return nullptr ; + // calcolo la polilinea che approssima la prima curva + PolyLine PL1 ; + if ( ! Curve1.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL1)) + return nullptr ; + // calcolo la polilinea che approssima la seconda curva + PolyLine PL2 ; + if ( ! Curve2.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL2)) + return nullptr ; + // creo e setto la superficie trimesh + PtrOwner pSTM( CreateSurfTriMesh()) ; + if ( IsNull( pSTM) || ! pSTM->CreateByTwoCurves( PL1, PL2)) + return nullptr ; + // restituisco la superficie + return Release( pSTM) ; +} diff --git a/StmFromTriangleSoup.cpp b/StmFromTriangleSoup.cpp index 396344e..9f4ac36 100644 --- a/StmFromTriangleSoup.cpp +++ b/StmFromTriangleSoup.cpp @@ -1,5 +1,5 @@ //---------------------------------------------------------------------------- -// EgalTech 2013-2014 +// EgalTech 2014-2015 //---------------------------------------------------------------------------- // File : StmFromTriangleSoup.cpp Data : 19.05.14 Versione : 1.5e7 // Contenuto : Implementazione della classe StmFromTriangleSoup, per creare diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index f5dd02f..42f5885 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -838,7 +838,7 @@ SurfTriMesh::AdjustTopology( void) bool SurfTriMesh::CreateByFlatContour( const PolyLine& PL) { - // eseguo la triangolazione + // eseguo la triangolazione, dopo aver verificato che il contorno sia chiuso e piatto PNTVECTOR vPnt ; INTVECTOR vTria ; Triangulate Tri ; diff --git a/Triangulate.cpp b/Triangulate.cpp index ac5851f..db0e986 100644 --- a/Triangulate.cpp +++ b/Triangulate.cpp @@ -27,7 +27,7 @@ using namespace std ; bool Triangulate::Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr) { - // verific che la polilinea sia chiusa e calcolo il piano medio del poligono + // verifico che la polilinea sia chiusa e piana e calcolo il piano medio del poligono double dArea ; Plane3d plPlane ; if ( ! PL.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))