EgtGeomKernel 1.5e2 :
- creazione STM per rototraslazione e da due curve.
This commit is contained in:
Binary file not shown.
+136
-109
@@ -855,48 +855,24 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
return false ;
|
||||
// recupero la tolleranza lineare
|
||||
double dLinTol = LIN_TOL_STD ;
|
||||
if ( vsParams.size() == 5)
|
||||
if ( vsParams.size() == 4)
|
||||
FromString( vsParams[3], dLinTol) ;
|
||||
// recupero la curva
|
||||
// recupero l'identificativo della curva
|
||||
int nIdCrv = GetIdParam( vsParams[2]) ;
|
||||
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento della curva
|
||||
Frame3d frCrv ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdCrv, frCrv))
|
||||
return false ;
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
// se i riferimenti sono uguali
|
||||
if ( AreSameFrame( frCrv, frDest)) {
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti devo prima trasformare la curva
|
||||
else {
|
||||
// creo una copia della curva (da buttare alla fine)
|
||||
PtrOwner<ICurve> pModCrv( GetCurve( pCrv->Clone())) ;
|
||||
if ( ! IsValid( pModCrv))
|
||||
return false ;
|
||||
// eseguo la trasformazione
|
||||
pModCrv->ToGlob( frCrv) ;
|
||||
pModCrv->ToLoc( frDest) ;
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pModCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
}
|
||||
if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL))
|
||||
return false ;
|
||||
// creo la superficie
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
if ( ! IsValid( pSTM))
|
||||
return false ;
|
||||
// costruisco la triangolazione
|
||||
if ( ! pSTM->CreateByTriangulation( PL))
|
||||
if ( ! pSTM->CreateByFlatContour( PL))
|
||||
return false ;
|
||||
// inserisco la superficie trimesh nel DB
|
||||
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
|
||||
@@ -912,38 +888,14 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
FromString( vsParams[4], dLinTol) ;
|
||||
// recupero la curva
|
||||
int nIdCrv = GetIdParam( vsParams[2]) ;
|
||||
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento della curva
|
||||
Frame3d frCrv ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdCrv, frCrv))
|
||||
return false ;
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
// se i riferimenti sono uguali
|
||||
if ( AreSameFrame( frCrv, frDest)) {
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti devo prima trasformare la curva
|
||||
else {
|
||||
// creo una copia della curva (da buttare alla fine)
|
||||
PtrOwner<ICurve> pModCrv( GetCurve( pCrv->Clone())) ;
|
||||
if ( ! IsValid( pModCrv))
|
||||
return false ;
|
||||
// eseguo la trasformazione
|
||||
pModCrv->ToGlob( frCrv) ;
|
||||
pModCrv->ToLoc( frDest) ;
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pModCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
}
|
||||
if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL))
|
||||
return false ;
|
||||
// recupero il vettore di estrusione
|
||||
Vector3d vtExtr ;
|
||||
if ( ! GetVectorParam( vsParams[3], vtExtr))
|
||||
@@ -958,81 +910,156 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// inserisco la superficie trimesh nel DB
|
||||
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
|
||||
}
|
||||
// se creazione per rivoluzione
|
||||
else if ( sCmd2 == "REV" || sCmd2 == "BYREVOLUTION") {
|
||||
// 6 o 7 parametri : Id, ParentId, IdCurve, ptRev, vtRev, dAngRot[, dLinTol]
|
||||
if ( vsParams.size() != 6 && vsParams.size() != 7)
|
||||
// se creazione da 2 percorsi
|
||||
else if ( sCmd2 == "2P" || sCmd2 == "BY2PATHS") {
|
||||
// 4 o 5 parametri : Id, ParentId, IdCurve1, IdCurve2[, dLinTol]
|
||||
if ( vsParams.size() != 4 && vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero la tolleranza lineare
|
||||
double dLinTol = LIN_TOL_STD ;
|
||||
if ( vsParams.size() == 7)
|
||||
FromString( vsParams[6], dLinTol) ;
|
||||
// recupero la curva
|
||||
int nIdCrv = GetIdParam( vsParams[2]) ;
|
||||
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento della curva
|
||||
Frame3d frCrv ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdCrv, frCrv))
|
||||
return false ;
|
||||
if ( vsParams.size() == 5)
|
||||
FromString( vsParams[4], dLinTol) ;
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
// se i riferimenti sono uguali
|
||||
if ( AreSameFrame( frCrv, frDest)) {
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti devo prima trasformare la curva
|
||||
else {
|
||||
// creo una copia della curva (da buttare alla fine)
|
||||
PtrOwner<ICurve> pModCrv( GetCurve( pCrv->Clone())) ;
|
||||
if ( ! IsValid( pModCrv))
|
||||
return false ;
|
||||
// eseguo la trasformazione
|
||||
pModCrv->ToGlob( frCrv) ;
|
||||
pModCrv->ToLoc( frDest) ;
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pModCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
}
|
||||
// recupero il punto dell'asse di rivoluzione
|
||||
Point3d ptAx ;
|
||||
if ( ! GetPointParam( vsParams[3], ptAx))
|
||||
// recupero l'identificativo della prima curva
|
||||
int nIdCrv1 = GetIdParam( vsParams[2]) ;
|
||||
// calcolo la polilinea che approssima la prima curva
|
||||
PolyLine PL1 ;
|
||||
if ( ! GetPolylineFromCurve( nIdCrv1, frDest, dLinTol, PL1))
|
||||
return false ;
|
||||
// recupero il vettore dell'asse di rivoluzione
|
||||
Vector3d vtAx ;
|
||||
if ( ! GetVectorParam( vsParams[4], vtAx))
|
||||
// recupero l'identificativo della seconda curva
|
||||
int nIdCrv2 = GetIdParam( vsParams[3]) ;
|
||||
// calcolo la polilinea che approssima la seconda curva
|
||||
PolyLine PL2 ;
|
||||
if ( ! GetPolylineFromCurve( nIdCrv2, frDest, dLinTol, PL2))
|
||||
return false ;
|
||||
// recupero l'angolo di rotazione
|
||||
double dAngRotDeg ;
|
||||
if ( ! FromString( vsParams[5], dAngRotDeg))
|
||||
return false ;
|
||||
// calcolo lo step di rotazione
|
||||
double dMaxRad = 0 ;
|
||||
PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) ;
|
||||
if ( dMaxRad < EPS_SMALL)
|
||||
return false ;
|
||||
double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ;
|
||||
// creo la superficie
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
if ( ! IsValid( pSTM))
|
||||
return false ;
|
||||
// costruisco la rivoluzione
|
||||
if ( ! pSTM->CreateByRevolution( PL, ptAx, vtAx, dAngRotDeg, dStepRotDeg))
|
||||
// costruisco la rigata tra le due curve
|
||||
if ( ! pSTM->CreateByTwoCurves( PL1, PL2))
|
||||
return false ;
|
||||
// inserisco la superficie trimesh nel DB
|
||||
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
|
||||
}
|
||||
// se creazione per rivoluzione
|
||||
else if ( sCmd2 == "REV" || sCmd2 == "BYREVOLUTION") {
|
||||
return SurfTriMeshByScrewing( false, vsParams) ;
|
||||
}
|
||||
// se creazione per rotoavvitamento
|
||||
else if ( sCmd2 == "SCR" || sCmd2 == "BYSCREWING") {
|
||||
return SurfTriMeshByScrewing( true, vsParams) ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbExecutor::SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams)
|
||||
{
|
||||
// default per tolleranza lineare e movimento lungo l'asse
|
||||
double dLinTol = LIN_TOL_STD ;
|
||||
double dMove = 0 ;
|
||||
// se previsto movimento
|
||||
if ( bMove) {
|
||||
// 7 o 8 parametri : Id, ParentId, IdCurve, ptRev, vtRev, dAngRot, dMove[, dLinTol]
|
||||
if ( vsParams.size() != 7 && vsParams.size() != 8)
|
||||
return false ;
|
||||
// recupero la tolleranza lineare
|
||||
if ( vsParams.size() == 8)
|
||||
FromString( vsParams[7], dLinTol) ;
|
||||
// recupero il movimento lungo l'asse
|
||||
if ( ! FromString( vsParams[6], dMove))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti con sola rotazione
|
||||
else {
|
||||
// 6 o 7 parametri : Id, ParentId, IdCurve, ptRev, vtRev, dAngRot[, dLinTol]
|
||||
if ( vsParams.size() != 6 && vsParams.size() != 7)
|
||||
return false ;
|
||||
// recupero la tolleranza lineare
|
||||
if ( vsParams.size() == 7)
|
||||
FromString( vsParams[6], dLinTol) ;
|
||||
// non c'é movimento lungo l'asse
|
||||
}
|
||||
// recupero l'identificativo della curva
|
||||
int nIdCrv = GetIdParam( vsParams[2]) ;
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL))
|
||||
return false ;
|
||||
// recupero il punto dell'asse di rivoluzione
|
||||
Point3d ptAx ;
|
||||
if ( ! GetPointParam( vsParams[3], ptAx))
|
||||
return false ;
|
||||
// recupero il vettore dell'asse di rivoluzione
|
||||
Vector3d vtAx ;
|
||||
if ( ! GetVectorParam( vsParams[4], vtAx))
|
||||
return false ;
|
||||
// recupero l'angolo di rotazione
|
||||
double dAngRotDeg ;
|
||||
if ( ! FromString( vsParams[5], dAngRotDeg))
|
||||
return false ;
|
||||
// calcolo lo step di rotazione
|
||||
double dMaxRad = 0 ;
|
||||
PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) ;
|
||||
if ( dMaxRad < EPS_SMALL)
|
||||
return false ;
|
||||
double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ;
|
||||
// creo la superficie
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
if ( ! IsValid( pSTM))
|
||||
return false ;
|
||||
// costruisco la rivoluzione
|
||||
if ( ! pSTM->CreateByScrewing( PL, ptAx, vtAx, dAngRotDeg, dStepRotDeg, dMove))
|
||||
return false ;
|
||||
// inserisco la superficie trimesh nel DB
|
||||
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbExecutor::GetPolylineFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyLine& PL)
|
||||
{
|
||||
// recupero la curva
|
||||
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nId)) ;
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento della curva
|
||||
Frame3d frCrv ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nId, frCrv))
|
||||
return false ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
// se i riferimenti sono uguali
|
||||
if ( AreSameFrame( frCrv, frDest)) {
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti devo prima trasformare la curva
|
||||
else {
|
||||
// creo una copia della curva (da buttare alla fine)
|
||||
PtrOwner<ICurve> pModCrv( GetCurve( pCrv->Clone())) ;
|
||||
if ( ! IsValid( pModCrv))
|
||||
return false ;
|
||||
// eseguo la trasformazione
|
||||
pModCrv->ToGlob( frCrv) ;
|
||||
pModCrv->ToLoc( frDest) ;
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pModCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbExecutor::AddGeoObj( const string& sId, const string& sIdParent, IGeoObj* pGeoObj)
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "/EgtDev/Include/EgtExecMgr.h"
|
||||
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||
|
||||
class PolyLine ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class GdbExecutor : public IGdbExecutor
|
||||
{
|
||||
@@ -43,6 +45,7 @@ class GdbExecutor : public IGdbExecutor
|
||||
bool GetPointWParam( const std::string& sParam, Point3d& ptP, double& dW) ;
|
||||
bool GetFrameParam( const std::string& sParam, Frame3d& frF) ;
|
||||
bool GetColorParam( const std::string& sParam, bool& bByParent, Color& cCol) ;
|
||||
bool GetPolylineFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyLine& PL) ;
|
||||
bool ExecuteGroup( const std::string& sCmd2, const STRVECTOR& vsParams) ;
|
||||
bool ExecutePoint( const std::string& sCmd2, const STRVECTOR& vsParams) ;
|
||||
bool ExecuteVector( const std::string& sCmd2, const STRVECTOR& vsParams) ;
|
||||
@@ -55,6 +58,7 @@ class GdbExecutor : public IGdbExecutor
|
||||
bool CurveCompoFromSplit( const STRVECTOR& vsParams) ;
|
||||
bool CurveCompoAddCurve( const STRVECTOR& vsParams) ;
|
||||
bool ExecuteSurfTriMesh( const std::string& sCmd2, const STRVECTOR& vsParams) ;
|
||||
bool SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams) ;
|
||||
bool ExecuteLevel( const std::string& sCmd2, const STRVECTOR& vsParams) ;
|
||||
bool ExecuteMode( const std::string& sCmd2, const STRVECTOR& vsParams) ;
|
||||
bool ExecuteStatus( const std::string& sCmd2, const STRVECTOR& vsParams) ;
|
||||
|
||||
+7
-3
@@ -110,7 +110,7 @@ PolyLine::Splice( PolyLine& PL)
|
||||
bool
|
||||
PolyLine::IsClosed( void) const
|
||||
{
|
||||
if ( m_lUPoints.empty())
|
||||
if ( m_lUPoints.size() < 3)
|
||||
return false ;
|
||||
|
||||
return ( AreSamePointNear( m_lUPoints.front().second, m_lUPoints.back().second)) ;
|
||||
@@ -134,11 +134,13 @@ PolyLine::GetFirstUPoint( double* pdPar, Point3d* pptP) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyLine::GetNextUPoint( double* pdPar, Point3d* pptP) const
|
||||
PolyLine::GetNextUPoint( double* pdPar, Point3d* pptP, bool bNotLast) const
|
||||
{
|
||||
++ m_iter ;
|
||||
if ( m_iter == m_lUPoints.end())
|
||||
return false ;
|
||||
if ( bNotLast && m_iter == -- ( m_lUPoints.end()))
|
||||
return false ;
|
||||
|
||||
if ( pdPar != nullptr)
|
||||
*pdPar = m_iter->first ;
|
||||
@@ -170,11 +172,13 @@ PolyLine::GetLastUPoint( double* pdPar, Point3d* pptP) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyLine::GetPrevUPoint( double* pdPar, Point3d* pptP) const
|
||||
PolyLine::GetPrevUPoint( double* pdPar, Point3d* pptP, bool bNotFirst) const
|
||||
{
|
||||
if ( m_iter == m_lUPoints.begin())
|
||||
return false ;
|
||||
-- m_iter ;
|
||||
if ( bNotFirst && m_iter == m_lUPoints.begin())
|
||||
return false ;
|
||||
|
||||
if ( pdPar != nullptr)
|
||||
*pdPar = m_iter->first ;
|
||||
|
||||
+373
-127
@@ -749,7 +749,7 @@ SurfTriMesh::AdjustTopology( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::CreateByTriangulation( const PolyLine& PL)
|
||||
SurfTriMesh::CreateByFlatContour( const PolyLine& PL)
|
||||
{
|
||||
// eseguo la triangolazione
|
||||
PNTVECTOR vPnt ;
|
||||
@@ -788,10 +788,14 @@ SurfTriMesh::CreateByTriangulation( const PolyLine& PL)
|
||||
bool
|
||||
SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
|
||||
{
|
||||
// verifico che il vettore di estrusione sia non nullo
|
||||
// il vettore di estrusione deve essere non nullo
|
||||
if ( vtExtr.IsSmall())
|
||||
return false ;
|
||||
|
||||
// la polilinea deve avere almeno 2 punti
|
||||
if ( PL.GetPointNbr() < 2)
|
||||
return false ;
|
||||
|
||||
// verifico se la polilinea è chiusa
|
||||
bool bClosed = PL.IsClosed() ;
|
||||
|
||||
@@ -801,44 +805,201 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
|
||||
return false ;
|
||||
|
||||
// inserisco il primo vertice della polilinea e il suo estruso
|
||||
int nP = 0 ;
|
||||
int nV = -1 ;
|
||||
Point3d ptP ;
|
||||
if ( ! PL.GetFirstPoint( ptP))
|
||||
return false ;
|
||||
++ nP ;
|
||||
if ( AddVertex( ptP) == SVT_NULL || AddVertex( ptP + vtExtr) == SVT_NULL)
|
||||
return false ;
|
||||
nV += 2 ;
|
||||
// ciclo sui punti della polilinea (per inserire vertice e suo estruso + 2 triangoli per ogni punto)
|
||||
int nIdV[4] ;
|
||||
while ( PL.GetNextPoint( ptP, bClosed)) {
|
||||
// aggiungo due nuovi vertici
|
||||
if ( AddVertex( ptP) == SVT_NULL || AddVertex( ptP + vtExtr) == SVT_NULL)
|
||||
return false ;
|
||||
nV += 2 ;
|
||||
// aggiungo i due triangoli relativi
|
||||
nIdV[0] = nV - 2 ;
|
||||
nIdV[1] = nV - 3 ;
|
||||
nIdV[2] = nV - 1 ;
|
||||
nIdV[3] = nV ;
|
||||
if ( ! AddBiTriangle( nIdV))
|
||||
return false ;
|
||||
}
|
||||
// se curva chiusa, aggiungo gli ultimi due triangoli
|
||||
if ( bClosed) {
|
||||
// non devo aggiungere i vertici, perchè coincidono con quelli iniziali
|
||||
// aggiungo i due triangoli relativi
|
||||
nIdV[0] = nV ;
|
||||
nIdV[1] = nV - 1 ;
|
||||
nIdV[2] = 0 ;
|
||||
nIdV[3] = 1 ;
|
||||
if ( ! AddBiTriangle( nIdV))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// sistemo la topologia
|
||||
return AdjustTopology() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2)
|
||||
{
|
||||
// verifico validità polilinee (devono avere almeno 2 punti e non coincidere se non agli estremi aperti)
|
||||
if ( ! VerifyPolylinesForTwoCurves( PL1, PL2))
|
||||
return false ;
|
||||
// flag di curve chiuse
|
||||
bool bClosed = PL1.IsClosed() && PL2.IsClosed() ;
|
||||
// recupero i parametri delle due polilinee
|
||||
double dU1F ; PL1.GetFirstU( dU1F) ;
|
||||
double dU1L ; PL1.GetLastU( dU1L) ;
|
||||
double dDeltaU1 = dU1L - dU1F ;
|
||||
if ( dDeltaU1 < EPS_SMALL)
|
||||
return false ;
|
||||
double dU2F ; PL2.GetFirstU( dU2F) ;
|
||||
double dU2L ; PL2.GetLastU( dU2L) ;
|
||||
double dDeltaU2 = dU2L - dU2F ;
|
||||
if ( dDeltaU2 < EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// costruisco la mesh
|
||||
int nPointNbr = PL1.GetPointNbr() + PL2.GetPointNbr() ;
|
||||
if ( ! Init( nPointNbr, nPointNbr))
|
||||
return false ;
|
||||
|
||||
// recupero i punti iniziali su curva 1
|
||||
int nV1p ; double dU1p ; double dA1p ; Point3d ptP1p ;
|
||||
int nV1s ; double dU1s ; double dA1s ; Point3d ptP1s ;
|
||||
bool bNext1 = PL1.GetFirstUPoint( &dU1p, &ptP1p) && PL1.GetNextUPoint( &dU1s, &ptP1s, bClosed) ;
|
||||
if ( ! bNext1)
|
||||
return false ;
|
||||
dA1p = 0 ;
|
||||
dA1s = ( dU1s - dU1F) / dDeltaU1 ;
|
||||
if ( ( nV1p = AddVertex( ptP1p)) == SVT_NULL)
|
||||
return false ;
|
||||
// recupero i punti iniziali su curva 2
|
||||
int nV2p ; double dU2p ; double dA2p ; Point3d ptP2p ;
|
||||
int nV2s ; double dU2s ; double dA2s ; Point3d ptP2s ;
|
||||
bool bNext2 = PL2.GetFirstUPoint( &dU2p, &ptP2p) && PL2.GetNextUPoint( &dU2s, &ptP2s, bClosed) ;
|
||||
if ( ! bNext2)
|
||||
return false ;
|
||||
dA2p = 0 ;
|
||||
dA2s = ( dU2s - dU2F) / dDeltaU2 ;
|
||||
int nIdV[3] ;
|
||||
while ( PL.GetNextPoint( ptP)) {
|
||||
// incremento numero punto
|
||||
++ nP ;
|
||||
// se polilinea aperta o non è l'ultimo punto
|
||||
if ( ! bClosed || nP < nPointNbr) {
|
||||
// aggiungo due nuovi vertici
|
||||
if ( AddVertex( ptP) == SVT_NULL || AddVertex( ptP + vtExtr) == SVT_NULL)
|
||||
// se i punti iniziali non coincidono, inserisco il vertice iniziale di 2
|
||||
if ( ! AreSamePointNear( ptP1p, ptP2p)) {
|
||||
if ( ( nV2p = AddVertex( ptP2p)) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti, inserisco un triangolo e mi sposto in avanti su entrambe le curve
|
||||
else {
|
||||
// inserisco il vertice A1s
|
||||
if ( ( nV1s = AddVertex( ptP1s)) == SVT_NULL)
|
||||
return false ;
|
||||
// inserisco il vertice A2s
|
||||
if ( ( nV2s = AddVertex( ptP2s)) == SVT_NULL)
|
||||
return false ;
|
||||
// inserisco il triangolo A1p -> A1s -> A2s
|
||||
nIdV[0] = nV1p ;
|
||||
nIdV[1] = nV1s ;
|
||||
nIdV[2] = nV2s ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// passo al punto successivo su 1
|
||||
nV1p = nV1s ; dA1p = dA1s ; dU1p = dU1s ; ptP1p = ptP1s ;
|
||||
bNext1 = PL1.GetNextUPoint( &dU1s, &ptP1s, bClosed) ;
|
||||
if ( bNext1)
|
||||
dA1s = ( dU1s - dU1F) / dDeltaU1 ;
|
||||
// passo al punto successivo su 2
|
||||
nV2p = nV2s ; dA2p = dA2s ; dU2p = dU2s ; ptP2p = ptP2s ;
|
||||
bNext2 = PL2.GetNextUPoint( &dU2s, &ptP2s, bClosed) ;
|
||||
if ( bNext2)
|
||||
dA2s = ( dU2s - dU2F) / dDeltaU2 ;
|
||||
}
|
||||
// ciclo sui punti
|
||||
while ( bNext1 || bNext2) {
|
||||
// se la diagonale più corta è dA2p -> dA1s
|
||||
if ( ( dA1s - dA2p) <= ( dA2s - dA1p) + EPS_PARAM) {
|
||||
// inserisco il vertice A1s
|
||||
if ( ( nV1s = AddVertex( ptP1s)) == SVT_NULL)
|
||||
return false ;
|
||||
nV += 2 ;
|
||||
// aggiungo triangolo in basso a sinistra
|
||||
nIdV[0] = nV - 3 ; nIdV[1] = nV - 1 ; nIdV[2] = nV - 2 ;
|
||||
// inserisco il triangolo A2p -> A1p -> A1s
|
||||
nIdV[0] = nV2p ;
|
||||
nIdV[1] = nV1p ;
|
||||
nIdV[2] = nV1s ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// aggiungo triangolo in alto a destra
|
||||
nIdV[0] = nV - 2 ; nIdV[1] = nV - 1 ; nIdV[2] = nV ;
|
||||
// se i punti correnti coincidono passo al successivo anche su 2
|
||||
if ( AreSamePointNear( ptP1s, ptP2s)) {
|
||||
nV2p = nV2s ; dA2p = dA2s ; dU2p = dU2s ; ptP2p = ptP2s ;
|
||||
bNext2 = PL2.GetNextUPoint( &dU2s, &ptP2s, bClosed) ;
|
||||
if ( bNext2)
|
||||
dA2s = ( dU2s - dU2F) / dDeltaU2 ;
|
||||
}
|
||||
// passo al punto successivo su 1
|
||||
nV1p = nV1s ; dA1p = dA1s ; dU1p = dU1s ; ptP1p = ptP1s ;
|
||||
bNext1 = PL1.GetNextUPoint( &dU1s, &ptP1s, bClosed) ;
|
||||
if ( bNext1)
|
||||
dA1s = ( dU1s - dU1F) / dDeltaU1 ;
|
||||
}
|
||||
// altrimenti è dA1p -> dA2s
|
||||
else {
|
||||
// inserisco il vertice A2s
|
||||
if ( ( nV2s = AddVertex( ptP2s)) == SVT_NULL)
|
||||
return false ;
|
||||
// inserisco il triangolo A2p -> A1p -> A2s
|
||||
nIdV[0] = nV2p ;
|
||||
nIdV[1] = nV1p ;
|
||||
nIdV[2] = nV2s ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// se i punti correnti coincidono passo al successivo anche su 1
|
||||
if ( AreSamePointNear( ptP1s, ptP2s)) {
|
||||
nV1p = nV1s ; dA1p = dA1s ; dU1p = dU1s ; ptP1p = ptP1s ;
|
||||
bNext1 = PL1.GetNextUPoint( &dU1s, &ptP1s, bClosed) ;
|
||||
if ( bNext1)
|
||||
dA1s = ( dU1s - dU1F) / dDeltaU1 ;
|
||||
}
|
||||
// passo al punto successivo su 2
|
||||
nV2p = nV2s ; dA2p = dA2s ; dU2p = dU2s ; ptP2p = ptP2s ;
|
||||
bNext2 = PL2.GetNextUPoint( &dU2s, &ptP2s, bClosed) ;
|
||||
if ( bNext2)
|
||||
dA2s = ( dU2s - dU2F) / dDeltaU2 ;
|
||||
}
|
||||
}
|
||||
// se curve chiuse, aggiungo gli ultimi due triangoli
|
||||
if ( bClosed) {
|
||||
dA1s = 1 ;
|
||||
dA2s = 1 ;
|
||||
// se la diagonale più corta è dA2p -> dA1s = 0
|
||||
if ( ( dA1s - dA2p) <= ( dA2s - dA1p) + EPS_PARAM) {
|
||||
// inserisco il triangolo A2p -> A1p -> A1s = 0
|
||||
nIdV[0] = nV2p ;
|
||||
nIdV[1] = nV1p ;
|
||||
nIdV[2] = 0 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// inserisco il triangolo A2p -> A1s = 0 -> A2s = 1
|
||||
nIdV[0] = nV2p ;
|
||||
nIdV[1] = 0 ;
|
||||
nIdV[2] = 1 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti ultimo punto di polilinea chiusa
|
||||
// altrimenti è dA1p -> dA2s = 1
|
||||
else {
|
||||
// non devo aggiungere i vertici, perchè coincidono con quelli iniziali
|
||||
// aggiungo triangolo in basso a sinistra
|
||||
nIdV[0] = nV - 1 ; nIdV[1] = 0 ; nIdV[2] = nV ;
|
||||
// inserisco il triangolo A2p -> A1p -> A2s = 1
|
||||
nIdV[0] = nV2p ;
|
||||
nIdV[1] = nV1p ;
|
||||
nIdV[2] = 1 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// aggiungo triangolo in alto a destra
|
||||
nIdV[0] = nV ; nIdV[1] = 0 ; nIdV[2] = 1 ;
|
||||
// inserisco il triangolo A1p -> A1s = 0 -> A2s = 1
|
||||
nIdV[0] = nV1p ;
|
||||
nIdV[1] = 0 ;
|
||||
nIdV[2] = 1 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
@@ -848,21 +1009,107 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
|
||||
return AdjustTopology() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& PL2) const
|
||||
{
|
||||
// recupero se chiusa
|
||||
bool bClosed = PL1.IsClosed() && PL2.IsClosed() ;
|
||||
// se chiuse, devono avere almeno 3 punti
|
||||
if ( bClosed) {
|
||||
if ( PL1.GetPointNbr() < 3 || PL2.GetPointNbr() < 3)
|
||||
return false ;
|
||||
}
|
||||
// se aperte, almeno 2
|
||||
else {
|
||||
if ( PL1.GetPointNbr() < 2 || PL2.GetPointNbr() < 2)
|
||||
return false ;
|
||||
}
|
||||
|
||||
// verifico che non ci siano punti interni in comune a pari parametro
|
||||
// recupero i parametri delle due polilinee
|
||||
double dU1F ; PL1.GetFirstU( dU1F) ;
|
||||
double dU1L ; PL1.GetLastU( dU1L) ;
|
||||
double dDeltaU1 = dU1L - dU1F ;
|
||||
if ( dDeltaU1 < EPS_SMALL)
|
||||
return false ;
|
||||
double dU2F ; PL2.GetFirstU( dU2F) ;
|
||||
double dU2L ; PL2.GetLastU( dU2L) ;
|
||||
double dDeltaU2 = dU2L - dU2F ;
|
||||
if ( dDeltaU2 < EPS_SMALL)
|
||||
return false ;
|
||||
// ciclo sui punti
|
||||
double dA1p ; double dU1p ; Point3d ptP1p ;
|
||||
double dA1s ; double dU1s ; Point3d ptP1s ;
|
||||
bool bNext1 = PL1.GetFirstUPoint( &dU1p, &ptP1p) && PL1.GetNextUPoint( &dU1s, &ptP1s) ;
|
||||
if ( ! bNext1)
|
||||
return false ;
|
||||
dA1p = 0 ;
|
||||
dA1s = ( dU1s - dU1F) / dDeltaU1 ;
|
||||
double dA2p ; double dU2s ; Point3d ptP2s ;
|
||||
double dA2s ; double dU2p ; Point3d ptP2p ;
|
||||
bool bNext2 = PL2.GetFirstUPoint( &dU2p, &ptP2p) && PL2.GetNextUPoint( &dU2s, &ptP2s) ;
|
||||
if ( ! bNext2)
|
||||
return false ;
|
||||
dA2p = 0 ;
|
||||
dA2s = ( dU2s - dU2F) / dDeltaU2 ;
|
||||
// se chiuse, verifico la coincidenza dell'inizio delle due curve
|
||||
if ( bClosed && AreSamePointNear( ptP1p, ptP2p))
|
||||
return false ;
|
||||
// verifiche sui punti successivi (non sugli ultimi)
|
||||
while ( bNext1 || bNext2) {
|
||||
// se la diagonale più corta è dA2p -> dA1s
|
||||
if ( ( dA1s - dA2p) <= ( dA2s - dA1p) + EPS_PARAM) {
|
||||
// verifico se coincidono
|
||||
if ( AreSamePointNear( ptP2p, ptP1s))
|
||||
return false ;
|
||||
// passo al punto successivo su 1
|
||||
dA1p = dA1s ; dU1p = dU1s ; ptP1p = ptP1s ;
|
||||
bNext1 = PL1.GetNextUPoint( &dU1s, &ptP1s, true) ;
|
||||
if ( bNext1)
|
||||
dA1s = ( dU1s - dU1F) / dDeltaU1 ;
|
||||
}
|
||||
// altrimenti è dA1p -> dA2s = 1
|
||||
else {
|
||||
// verifico se coincidono
|
||||
if ( AreSamePointNear( ptP1p, ptP2s))
|
||||
return false ;
|
||||
// passo al punto successivo su 2
|
||||
dA2p = dA2s ; dU2p = dU2s ; ptP2p = ptP2s ;
|
||||
bNext2 = PL2.GetNextUPoint( &dU2s, &ptP2s, true) ;
|
||||
if ( bNext2)
|
||||
dA2s = ( dU2s - dU2F) / dDeltaU2 ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::CreateByRevolution( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
double dAngRot, double dStepRot)
|
||||
{
|
||||
return CreateByScrewing( PL, ptAx, vtAx, dAngRot, dStepRot, 0) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
double dAngRot, double dStepRot, double dMove)
|
||||
{
|
||||
// verifico che l'asse di rotazione sia non nullo
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
// verifico che l'angolo di rotazione sia significativo e non superi un giro
|
||||
// verifico se solo rivoluzione
|
||||
bool bOnlyRev = ( fabs( dMove) < EPS_SMALL) ;
|
||||
// verifico che l'angolo di rotazione sia significativo e, se solo rivoluzione, non superi un giro
|
||||
if ( fabs( dAngRot) < EPS_ANG_SMALL)
|
||||
return false ;
|
||||
if ( fabs( dAngRot) > ANG_FULL)
|
||||
if ( bOnlyRev && fabs( dAngRot) > ANG_FULL)
|
||||
dAngRot = _copysign( ANG_FULL, dAngRot) ;
|
||||
// verifico se rotazione completa
|
||||
bool bFullRev = ( fabs( fabs( dAngRot) - ANG_FULL) < EPS_ANG_SMALL) ;
|
||||
bool bFullRev = bOnlyRev && ( fabs( fabs( dAngRot) - ANG_FULL) < EPS_ANG_SMALL) ;
|
||||
// aggiusto il valore dell'angolo di step
|
||||
const double MIN_STEP_ROT = 1 ;
|
||||
const double MAX_STEP_ROT = 90 ;
|
||||
@@ -875,7 +1122,9 @@ SurfTriMesh::CreateByRevolution( const PolyLine& PL, const Point3d& ptAx, const
|
||||
// calcolo il numero di step
|
||||
int nStep = int( dAngRot / dStepRot) ;
|
||||
nStep = max( nStep, 1) ;
|
||||
dStepRot = dAngRot / nStep ;
|
||||
double dCosStepRot = cos( dAngRot / nStep * DEGTORAD) ;
|
||||
double dSinStepRot = sin( dAngRot / nStep * DEGTORAD) ;
|
||||
Vector3d vtStepMove = ( dMove / nStep) * vtAx ;
|
||||
if ( bFullRev)
|
||||
-- nStep ;
|
||||
|
||||
@@ -894,24 +1143,24 @@ SurfTriMesh::CreateByRevolution( const PolyLine& PL, const Point3d& ptAx, const
|
||||
return false ;
|
||||
|
||||
// inserisco il primo punto della polilinea e i suoi ruotati
|
||||
int nP = 0 ;
|
||||
int nV = -1 ;
|
||||
Point3d ptP ;
|
||||
// recupero il punto
|
||||
if ( ! PL.GetFirstPoint( ptP))
|
||||
return false ;
|
||||
++ nP ;
|
||||
// inserisco il primo vertice
|
||||
if ( AddVertex( ptP) == SVT_NULL)
|
||||
return false ;
|
||||
++ nV ;
|
||||
// verifico se il punto giace sull'asse
|
||||
bool bPrevOnAx = DistPointLine( ptP, ptAx, vtAx, 1, false).IsSmall() ;
|
||||
// verifico se il punto giace sull'asse e vi sta fisso
|
||||
bool bPrevOnAx = bOnlyRev && DistPointLine( ptP, ptAx, vtAx, 1, false).IsSmall() ;
|
||||
int nVPrevOnAx = nV ;
|
||||
// se non è sull'asse, inserisco le copie ruotate
|
||||
// se non è fisso sull'asse, inserisco le copie ruotate
|
||||
if ( ! bPrevOnAx) {
|
||||
for ( int i = 1 ; i <= nStep ; ++i) {
|
||||
ptP.Rotate( ptAx, vtAx, dStepRot * DEGTORAD) ;
|
||||
ptP.Rotate( ptAx, vtAx, dCosStepRot, dSinStepRot) ;
|
||||
if ( ! bOnlyRev)
|
||||
ptP.Translate( vtStepMove) ;
|
||||
if ( AddVertex( ptP) == SVT_NULL)
|
||||
return false ;
|
||||
++ nV ;
|
||||
@@ -919,108 +1168,105 @@ SurfTriMesh::CreateByRevolution( const PolyLine& PL, const Point3d& ptAx, const
|
||||
}
|
||||
// ciclo sui punti della polilinea (per inserire vertice e suoi ruotati + 2 triangoli per ogni punto)
|
||||
int nIdV[4] ;
|
||||
while ( PL.GetNextPoint( ptP)) {
|
||||
// incremento numero punto
|
||||
++ nP ;
|
||||
// se polilinea aperta o non è l'ultimo punto
|
||||
if ( ! bClosed || nP < nPointNbr) {
|
||||
// aggiungo il primo vertice
|
||||
if ( AddVertex( ptP) == SVT_NULL)
|
||||
return false ;
|
||||
++ nV ;
|
||||
// verifico se il punto giace sull'asse
|
||||
bool bOnAx = DistPointLine( ptP, ptAx, vtAx, 1, false).IsSmall() ;
|
||||
// ciclo sugli step
|
||||
for ( int i = 1 ; i <= nStep ; ++i) {
|
||||
// se non è sull'asse, inserisco le copie ruotate
|
||||
if ( ! bOnAx) {
|
||||
ptP.Rotate( ptAx, vtAx, dStepRot * DEGTORAD) ;
|
||||
if ( AddVertex( ptP) == SVT_NULL)
|
||||
return false ;
|
||||
++ nV ;
|
||||
}
|
||||
// per i controlli già fatti non è possibile avere contemp. prec e corr su asse
|
||||
// se il precedente è sull'asse, aggiungo un solo triangolo
|
||||
if ( bPrevOnAx) {
|
||||
nIdV[0] = nVPrevOnAx ;
|
||||
nIdV[1] = nV ;
|
||||
nIdV[2] = nV - 1 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// se il corrente è sull'asse, aggiungo un solo triangolo
|
||||
else if ( bOnAx) {
|
||||
nIdV[0] = nV - ( nStep + 2) + i ;
|
||||
nIdV[1] = nIdV[0] + 1 ;
|
||||
nIdV[2] = nV ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti aggiungo due triangoli
|
||||
else {
|
||||
nIdV[0] = nV - ( nStep + 2) ;
|
||||
nIdV[1] = nIdV[0] + 1 ;
|
||||
nIdV[2] = nV ;
|
||||
nIdV[3] = nV - 1 ;
|
||||
if ( ! AddBiTriangle( nIdV))
|
||||
return false ;
|
||||
}
|
||||
while ( PL.GetNextPoint( ptP, bClosed)) {
|
||||
// aggiungo il primo vertice
|
||||
if ( AddVertex( ptP) == SVT_NULL)
|
||||
return false ;
|
||||
++ nV ;
|
||||
// verifico se il punto giace sull'asse e vi sta fisso
|
||||
bool bOnAx = bOnlyRev && DistPointLine( ptP, ptAx, vtAx, 1, false).IsSmall() ;
|
||||
// ciclo sugli step
|
||||
for ( int i = 1 ; i <= nStep ; ++i) {
|
||||
// se non è fisso sull'asse, inserisco le copie ruotate
|
||||
if ( ! bOnAx) {
|
||||
ptP.Rotate( ptAx, vtAx, dCosStepRot, dSinStepRot) ;
|
||||
if ( ! bOnlyRev)
|
||||
ptP.Translate( vtStepMove) ;
|
||||
if ( AddVertex( ptP) == SVT_NULL)
|
||||
return false ;
|
||||
++ nV ;
|
||||
}
|
||||
// se rivoluzione completa, aggiungo i due triangoli di chiusura
|
||||
if ( bFullRev) {
|
||||
// per i controlli già fatti non è possibile avere contemp. prec e corr su asse
|
||||
// se il precedente è sull'asse, aggiungo un solo triangolo
|
||||
if ( bPrevOnAx) {
|
||||
nIdV[0] = nVPrevOnAx ;
|
||||
nIdV[1] = nV - nStep ;
|
||||
nIdV[2] = nV ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// se il corrente è sull'asse, aggiungo un solo triangolo
|
||||
else if ( bOnAx) {
|
||||
nIdV[0] = nV - 1 ;
|
||||
nIdV[1] = nV - ( nStep + 1) ;
|
||||
nIdV[2] = nV ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti aggiungo due triangoli
|
||||
else {
|
||||
nIdV[0] = nV - ( nStep + 1) ;
|
||||
nIdV[1] = nV - ( 2 * nStep + 1) ;
|
||||
nIdV[2] = nV - nStep ;
|
||||
nIdV[3] = nV ;
|
||||
if ( ! AddBiTriangle( nIdV))
|
||||
return false ;
|
||||
}
|
||||
// per i controlli già fatti non è possibile avere contemp. prec e corr su asse
|
||||
// se il precedente è sull'asse, aggiungo un solo triangolo
|
||||
if ( bPrevOnAx) {
|
||||
nIdV[0] = nVPrevOnAx ;
|
||||
nIdV[1] = nV ;
|
||||
nIdV[2] = nV - 1 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// se il corrente è sull'asse, aggiungo un solo triangolo
|
||||
else if ( bOnAx) {
|
||||
nIdV[0] = nV - ( nStep + 2) + i ;
|
||||
nIdV[1] = nIdV[0] + 1 ;
|
||||
nIdV[2] = nV ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti aggiungo due triangoli
|
||||
else {
|
||||
nIdV[0] = nV - ( nStep + 2) ;
|
||||
nIdV[1] = nIdV[0] + 1 ;
|
||||
nIdV[2] = nV ;
|
||||
nIdV[3] = nV - 1 ;
|
||||
if ( ! AddBiTriangle( nIdV))
|
||||
return false ;
|
||||
}
|
||||
bPrevOnAx = false ;
|
||||
}
|
||||
// altrimenti ultimo punto di polilinea chiusa
|
||||
else {
|
||||
for ( int i = 1 ; i <= nStep ; ++i) {
|
||||
// non devo aggiungere i vertici, perchè coincidono con quelli iniziali
|
||||
// aggiungo triangolo in basso a sinistra
|
||||
nIdV[0] = nV - nStep + i - 1 ; nIdV[1] = nV - nStep + i ; nIdV[2] = i ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// aggiungo triangolo in alto a destra
|
||||
nIdV[0] = nV - nStep + i - 1 ; nIdV[1] = i ; nIdV[2] = i - 1 ;
|
||||
// se rivoluzione completa, aggiungo i due triangoli di chiusura
|
||||
if ( bFullRev) {
|
||||
// per i controlli già fatti non è possibile avere contemp. prec e corr su asse
|
||||
// se il precedente è sull'asse, aggiungo un solo triangolo
|
||||
if ( bPrevOnAx) {
|
||||
nIdV[0] = nVPrevOnAx ;
|
||||
nIdV[1] = nV - nStep ;
|
||||
nIdV[2] = nV ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// se rivoluzione completa, aggiungo i due triangoli di chiusura
|
||||
if ( bFullRev) {
|
||||
// aggiungo triangolo in basso a sinistra
|
||||
nIdV[0] = nV ; nIdV[1] = nV - nStep ; nIdV[2] = 0 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// aggiungo triangolo in alto a destra
|
||||
nIdV[0] = nV ; nIdV[1] = 0 ; nIdV[2] = nStep ;
|
||||
// se il corrente è sull'asse, aggiungo un solo triangolo
|
||||
else if ( bOnAx) {
|
||||
nIdV[0] = nV - 1 ;
|
||||
nIdV[1] = nV - ( nStep + 1) ;
|
||||
nIdV[2] = nV ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti aggiungo due triangoli
|
||||
else {
|
||||
nIdV[0] = nV - ( nStep + 1) ;
|
||||
nIdV[1] = nV - ( 2 * nStep + 1) ;
|
||||
nIdV[2] = nV - nStep ;
|
||||
nIdV[3] = nV ;
|
||||
if ( ! AddBiTriangle( nIdV))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
bPrevOnAx = false ;
|
||||
}
|
||||
// altrimenti ultimo punto di polilinea chiusa
|
||||
if ( bClosed) {
|
||||
for ( int i = 1 ; i <= nStep ; ++i) {
|
||||
// non devo aggiungere i vertici, perchè coincidono con quelli iniziali
|
||||
// aggiungo triangolo in basso a sinistra
|
||||
nIdV[0] = nV - nStep + i - 1 ; nIdV[1] = nV - nStep + i ; nIdV[2] = i ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// aggiungo triangolo in alto a destra
|
||||
nIdV[0] = nV - nStep + i - 1 ; nIdV[1] = i ; nIdV[2] = i - 1 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// se rivoluzione completa, aggiungo i due triangoli di chiusura
|
||||
if ( bFullRev) {
|
||||
// aggiungo triangolo in basso a sinistra
|
||||
nIdV[0] = nV ; nIdV[1] = nV - nStep ; nIdV[2] = 0 ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
// aggiungo triangolo in alto a destra
|
||||
nIdV[0] = nV ; nIdV[1] = 0 ; nIdV[2] = nStep ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1078,9 +1324,9 @@ SurfTriMesh::AddBiTriangle( const int nIdVert[4])
|
||||
// | |
|
||||
// 1 -> 2
|
||||
int nIdV[3] ;
|
||||
// se la diagonale 0->2 è più corta della 1->3
|
||||
// se la diagonale 0->2 è uguale o più corta della 1->3
|
||||
if ( SqDist( m_vVert[nIdVert[0]].ptP, m_vVert[nIdVert[2]].ptP) <=
|
||||
SqDist( m_vVert[nIdVert[1]].ptP, m_vVert[nIdVert[3]].ptP)) {
|
||||
SqDist( m_vVert[nIdVert[1]].ptP, m_vVert[nIdVert[3]].ptP) + EPS_SMALL) {
|
||||
// triangolo 0->1->2
|
||||
nIdV[0] = nIdVert[0] ;
|
||||
nIdV[1] = nIdVert[1] ;
|
||||
|
||||
+6
-2
@@ -95,10 +95,13 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
virtual int AddVertex( const Point3d& ptVert) ;
|
||||
virtual int AddTriangle( const int nIdVert[3]) ;
|
||||
virtual bool AdjustTopology( void) ;
|
||||
virtual bool CreateByTriangulation( const PolyLine& PL) ;
|
||||
virtual bool CreateByFlatContour( const PolyLine& PL) ;
|
||||
virtual bool CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) ;
|
||||
virtual bool CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2) ;
|
||||
virtual bool CreateByRevolution( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
double dAngRot, double dStepRot) ;
|
||||
virtual bool CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
double dAngRot, double dStepRot, double dMove) ;
|
||||
virtual int GetVertexNum( void) const
|
||||
{ return int( m_vVert.size()) ; }
|
||||
virtual int GetTriangleNum( void) const
|
||||
@@ -140,8 +143,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
int NextIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
|
||||
int PrevIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
|
||||
bool GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const ;
|
||||
bool VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& PL2) const ;
|
||||
bool VeryfyPolylineForRevolution( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx) const ;
|
||||
bool AddBiTriangle( const int nIdVert[4]) ;
|
||||
bool AddBiTriangle( const int nIdVert[4]) ;
|
||||
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
|
||||
Reference in New Issue
Block a user