EgtGeomKernel 1.6h3 :
- migliorata approssimazione curve per riconoscimento di tratti rettilinei - aggiunta CopyMaterial a GeomDB - correzioni a IntersCurveCurve per le curve approssimate - aggiunte a Intervals Union, Intersection e Difference - correzioni a SelfIntersCurve per curve approssimate - aggiunte funzioni di creazione Regioni (Rectangle, Stadium, Disk e da zuppa di curve) - migliorie varie a Regioni e introduzione dei componenti connessi (chunk).
This commit is contained in:
+247
@@ -0,0 +1,247 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 "CurveArc.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionRectangle( double dWidth, double dLen)
|
||||
{
|
||||
// le dimensioni devono essere significative
|
||||
if ( dWidth < EPS_SMALL || dLen < EPS_SMALL)
|
||||
return nullptr ;
|
||||
// creo il contorno
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ORIG) ;
|
||||
PL.AddUPoint( 1, Point3d( dWidth, 0, 0)) ;
|
||||
PL.AddUPoint( 2, Point3d( dWidth, dLen, 0)) ;
|
||||
PL.AddUPoint( 3, Point3d( 0, dLen, 0)) ;
|
||||
PL.AddUPoint( 4, ORIG) ;
|
||||
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCC) || ! pCC->FromPolyLine( PL))
|
||||
return nullptr ;
|
||||
// creo il rettangolo
|
||||
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pCC)))
|
||||
return nullptr ;
|
||||
else
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionStadium( double dWidth, double dLen)
|
||||
{
|
||||
// le dimensioni devono essere significative
|
||||
if ( dWidth < EPS_SMALL || dLen < EPS_SMALL)
|
||||
return nullptr ;
|
||||
// se dimensioni praticamente uguali, è un disco
|
||||
if ( fabs( dWidth - dLen) < 10 * EPS_SMALL)
|
||||
return GetSurfFlatRegionDisk( ( dWidth + dLen) / 4) ;
|
||||
// creo il contorno
|
||||
PolyArc PA ;
|
||||
if ( dWidth > dLen) {
|
||||
double dRad = dLen / 2 ;
|
||||
PA.AddUPoint( 0, Point3d( dRad, 0, 0), 0) ;
|
||||
PA.AddUPoint( 1, Point3d( dWidth - dRad, 0, 0), 1) ;
|
||||
PA.AddUPoint( 2, Point3d( dWidth - dRad, dLen, 0), 0) ;
|
||||
PA.AddUPoint( 3, Point3d( dRad, dLen, 0), 1) ;
|
||||
PA.AddUPoint( 4, Point3d( dRad, 0, 0), 0) ;
|
||||
}
|
||||
else {
|
||||
double dRad = dWidth / 2 ;
|
||||
PA.AddUPoint( 0, Point3d( dWidth, dRad, 0), 0) ;
|
||||
PA.AddUPoint( 1, Point3d( dWidth, dLen - dRad, 0), 1) ;
|
||||
PA.AddUPoint( 2, Point3d( 0, dLen - dRad, 0), 0) ;
|
||||
PA.AddUPoint( 3, Point3d( 0, dRad, 0), 1) ;
|
||||
PA.AddUPoint( 4, Point3d( dWidth, dRad, 0), 0) ;
|
||||
}
|
||||
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCC) || ! pCC->FromPolyArc( PA))
|
||||
return nullptr ;
|
||||
// creo il rettangolo
|
||||
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pCC)))
|
||||
return nullptr ;
|
||||
else
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionDisk( double dRadius)
|
||||
{
|
||||
// le dimensioni devono essere significative
|
||||
if ( dRadius < EPS_SMALL)
|
||||
return nullptr ;
|
||||
// creo la circonferenza di riferimento
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
pArc->Set( ORIG, Z_AX, dRadius, X_AX, ANG_FULL, 0) ;
|
||||
// creo il disco
|
||||
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pArc)))
|
||||
return nullptr ;
|
||||
else
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Classe SurfFlatRegionByContours
|
||||
//-------------------------------------------------------------------------------
|
||||
SurfFlatRegionByContours::~SurfFlatRegionByContours(void)
|
||||
{
|
||||
// cancello eventuali curve rimaste
|
||||
for ( auto& pCrv : m_vpCrv) {
|
||||
if ( pCrv != nullptr)
|
||||
delete pCrv ;
|
||||
pCrv = nullptr ;
|
||||
}
|
||||
m_vpCrv.clear() ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegionByContours::AddCurve( ICurve* pCrv)
|
||||
{
|
||||
// acquisisco la curva
|
||||
PtrOwner<ICurve> pMyCrv( pCrv) ;
|
||||
if ( IsNull( pMyCrv) || ! pMyCrv->IsValid())
|
||||
return false ;
|
||||
// verifico sia chiusa
|
||||
if ( ! pMyCrv->IsClosed())
|
||||
return false ;
|
||||
// la inserisco nel vettore delle curve
|
||||
m_vpCrv.push_back( Release( pMyCrv)) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegionByContours::Prepare( void)
|
||||
{
|
||||
// calcolo piano medio e area delle curve
|
||||
m_vArea.reserve( m_vpCrv.size()) ;
|
||||
Vector3d vtN0 ;
|
||||
for ( int i = 0 ; i < int( m_vpCrv.size()) ; ++ i) {
|
||||
// calcolo piano medio e area
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! m_vpCrv[i]->GetArea( plPlane, dArea))
|
||||
return false ;
|
||||
// imposto la normale del primo contorno come riferimento
|
||||
if ( i == 0)
|
||||
vtN0 = plPlane.vtN ;
|
||||
// verifico che le normali siano molto vicine
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.vtN, vtN0))
|
||||
return false ;
|
||||
// assegno il segno all'area secondo il verso della normale
|
||||
if ( ( plPlane.vtN * vtN0) > 0)
|
||||
m_vArea.emplace_back( i, dArea) ;
|
||||
else
|
||||
m_vArea.emplace_back( i, - dArea) ;
|
||||
}
|
||||
// ordino in senso decrescente sull'area
|
||||
sort( m_vArea.begin(), m_vArea.end(),
|
||||
[]( const INDAREA& a, const INDAREA&b) { return fabs( a.second) > fabs( b.second) ; }) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
SurfFlatRegionByContours::GetSurf( void)
|
||||
{
|
||||
// se è la prima superficie, devo preparare
|
||||
if ( m_bFirst) {
|
||||
if ( ! Prepare())
|
||||
return nullptr ;
|
||||
m_bFirst = false ;
|
||||
}
|
||||
// altrimenti, se ammessa una sola superficie errore
|
||||
else if ( ! m_bAllowedMore) {
|
||||
return nullptr ;
|
||||
}
|
||||
// creo la superficie
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// aggiungo le diverse curve
|
||||
bool bFirstCrv ;
|
||||
do {
|
||||
bFirstCrv = true ;
|
||||
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
|
||||
// recupero indice di percorso e verifico sia valido
|
||||
int j = m_vArea[i].first ;
|
||||
if ( j < 0)
|
||||
continue ;
|
||||
// la prima deve essere il loop esterno
|
||||
if ( bFirstCrv) {
|
||||
// ne faccio una copia
|
||||
PtrOwner<ICurve> pCrv( m_vpCrv[j]->Clone()) ;
|
||||
if ( IsNull( pCrv)) {
|
||||
m_vArea[i].first = - 1 ;
|
||||
continue ;
|
||||
}
|
||||
// provo a inserirla
|
||||
if ( pSfr->AddExtLoop( Release( pCrv))) {
|
||||
bFirstCrv = false ;
|
||||
delete m_vpCrv[j] ;
|
||||
m_vpCrv[j] = nullptr ;
|
||||
m_vArea[i].first = - 1 ;
|
||||
}
|
||||
}
|
||||
// gli altri sono loop interni
|
||||
else {
|
||||
// ne faccio una copia
|
||||
PtrOwner<ICurve> pCrv( m_vpCrv[j]->Clone()) ;
|
||||
if ( IsNull( pCrv)) {
|
||||
m_vArea[i].first = - 1 ;
|
||||
continue ;
|
||||
}
|
||||
// provo a inserirla
|
||||
if ( pSfr->AddIntLoop( Release( pCrv))) {
|
||||
delete m_vpCrv[j] ;
|
||||
m_vpCrv[j] = nullptr ;
|
||||
m_vArea[i].first = - 1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( m_bAllowedMultiChunk && ! bFirstCrv) ;
|
||||
// se non valida, errore
|
||||
if ( ! pSfr->IsValid())
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegionByContours::AllCurvesUsed( void)
|
||||
{
|
||||
// verifico se cono rimaste delle curve
|
||||
for ( auto& pCrv : m_vpCrv) {
|
||||
if ( pCrv != nullptr)
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
Reference in New Issue
Block a user