diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc
index 8427a4c..b6410ac 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
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))