EgtGeomKernel :
- correzioni e migliorie a offset3d - creato enum per angoli di una curva proiettata su superficie. - aggiunta funzione per l'estensione delle superfici.
This commit is contained in:
+31
-23
@@ -61,7 +61,7 @@ OffsetCurve3d::Reset( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOffDist, int nType)
|
||||
OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
||||
{
|
||||
// la funzione è pensata per lavorare con il risultato dell'operazione ProjectCurveOnSurf
|
||||
|
||||
@@ -70,6 +70,18 @@ OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOff
|
||||
|
||||
// pulisco tutto
|
||||
Reset() ;
|
||||
|
||||
INTVECTOR vFlag ;
|
||||
VCT3DVECTOR vOffDir ;
|
||||
PolyLine PL ;
|
||||
for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) {
|
||||
PL.AddUPoint( i, vPnt5Ax[i].ptP) ;
|
||||
vOffDir.push_back( vPnt5Ax[i].vtDir1) ;
|
||||
if ( vPnt5Ax[i].nFlag > 0)
|
||||
vFlag.push_back( vPnt5Ax[i].nFlag) ;
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
PtrOwner<CurveComposite> pCrv( CreateBasicCurveComposite()) ;
|
||||
if ( ! pCrv->FromPolyLine( PL))
|
||||
return false ;
|
||||
@@ -116,25 +128,6 @@ OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOff
|
||||
|
||||
bool bClosed = pCrv->IsClosed() ;
|
||||
|
||||
INTVECTOR vFlag ;
|
||||
vFlag.push_back( OffsetCurve3d::AngType::ANG_STR) ;
|
||||
const ICurve* pSubCrv = pCrv->GetFirstCurve() ;
|
||||
const double dSinAngSmall = sin( 1 * DEGTORAD) ;
|
||||
for ( int i = 1 ; i < pCrv->GetCurveCount() ; ++i) {
|
||||
pSubCrv = pCrv->GetNextCurve() ;
|
||||
Vector3d vtDirCurr ; pSubCrv->GetStartDir( vtDirCurr) ;
|
||||
vtDirCurr.Normalize() ;
|
||||
int nFlag ;
|
||||
double dProj = vtDirCurr * vOffDir[i-1] ;
|
||||
if ( dProj > dSinAngSmall)
|
||||
nFlag = OffsetCurve3d::AngType::ANG_SMOOTH_CONC ;
|
||||
else if ( dProj > - dSinAngSmall)
|
||||
nFlag = OffsetCurve3d::AngType::ANG_STR ;
|
||||
else
|
||||
nFlag = OffsetCurve3d::AngType::ANG_CVEX ;
|
||||
vFlag.push_back( nFlag) ;
|
||||
}
|
||||
|
||||
for ( int i = 1 ; i < ssize( vFlag) - 1 ; ++i) {
|
||||
if ( vFlag[i-1] == OffsetCurve3d::AngType::ANG_SMOOTH_CONC &&
|
||||
vFlag[i+1] == OffsetCurve3d::AngType::ANG_SMOOTH_CONC &&
|
||||
@@ -148,12 +141,23 @@ OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOff
|
||||
Vector3d vtCorrPrev ;
|
||||
Vector3d vtTangPrev ;
|
||||
Vector3d vtDirPrev ; pCrv->GetStartDir( vtDirPrev) ;
|
||||
if ( bClosed) {
|
||||
Vector3d vtDirLast ; pCrv->GetEndDir( vtDirLast) ;
|
||||
if ( vFlag[0] != OffsetCurve3d::AngType::ANG_CVEX)
|
||||
vtTangPrev = Media( vtDirLast, vtDirPrev) ;
|
||||
else if ( vFlag[0] == OffsetCurve3d::AngType::ANG_CVEX && vFlag.back() != OffsetCurve3d::AngType::ANG_CVEX)
|
||||
vtTangPrev = vtDirLast ;
|
||||
else
|
||||
vtTangPrev = vtDirPrev ;
|
||||
}
|
||||
const ICurve* pCrvPrev = pCrv->GetFirstCurve() ;
|
||||
const ICurve* pCrvCurr ;
|
||||
OFFSETSEGVEC vOffsetCrvs ;
|
||||
Vector3d vtDirPrevOff = V_INVALID ;
|
||||
for ( int i = 1 ; i < pCrv->GetCurveCount() ; ++i) {
|
||||
for ( int i = 1 ; i <= pCrv->GetCurveCount() ; ++i) {
|
||||
pCrvCurr = pCrv->GetNextCurve() ;
|
||||
if ( pCrvCurr == nullptr && bClosed && vFlag[i] == OffsetCurve3d::AngType::ANG_CVEX)
|
||||
pCrvCurr = pCrv->GetFirstCurve() ;
|
||||
Vector3d vtOffDir = vOffDir[i] ;
|
||||
Vector3d vtDirCurr ; pCrvCurr->GetStartDir( vtDirCurr) ;
|
||||
pCrvPrev->GetStartDir( vtDirPrev) ;
|
||||
@@ -239,7 +243,8 @@ OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOff
|
||||
Point3d ptP ; vOffsetCrvs.front().pCrv->GetStartPoint( ptP) ;
|
||||
ICurveLine* pCL = CreateBasicCurveLine() ;
|
||||
pCL->Set( ptPrev, ptP) ;
|
||||
vOffsetCrvs.emplace_back( pCL, OffsetCurve3d::AngType::ANG_STR, -1) ;
|
||||
if ( pCL->IsValid())
|
||||
vOffsetCrvs.emplace_back( pCL, OffsetCurve3d::AngType::ANG_STR, -1) ;
|
||||
}
|
||||
|
||||
// qui faccio la correzione per gli angoli interni
|
||||
@@ -400,7 +405,10 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
|
||||
while ( nFlag == OffsetCurve3d::AngType::ANG_SMOOTH_CONC) {
|
||||
vLines.push_back( i) ;
|
||||
++i ;
|
||||
nFlag = vOffsetCrvs[i].nFlag ;
|
||||
if ( i < ssize( vOffsetCrvs))
|
||||
nFlag = vOffsetCrvs[i].nFlag ;
|
||||
else
|
||||
nFlag = OffsetCurve3d::AngType::ANG_STR ;
|
||||
}
|
||||
CYLVECT vCyl ;
|
||||
// creo un cilindro della dimensione del raggio
|
||||
|
||||
+42
-17
@@ -32,15 +32,6 @@ using namespace std ;
|
||||
const double COS_ANG_LIM = 0.0175 ;
|
||||
// Angolo massimo tra normali per effettuare bisezione su spigolo
|
||||
const double COS_ANG_MAX_CORNER = 0.8660 ;
|
||||
// Tipologia di punto
|
||||
const int P5AX_TO_DELETE = -1 ; // da cancellare
|
||||
const int P5AX_OUT = 0 ; // aggiunto prima di inizio o dopo fine
|
||||
const int P5AX_STD = 1 ; // standard
|
||||
const int P5AX_CVEX = 2 ; // su angolo convesso
|
||||
const int P5AX_CONC = 3 ; // in angolo concavo
|
||||
const int P5AX_BEFORE_CONC = 4 ; // adiacente ad angolo concavo
|
||||
const int P5AX_AFTER_CONC = 5 ; // adiacente ad angolo concavo
|
||||
const int P5AX_SMOOTH_CONC = 6 ; // zona concava curva, senza spigolo netto
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static double
|
||||
@@ -65,7 +56,7 @@ PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext,
|
||||
static bool
|
||||
AddPointsOnCorners( PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
const double dSinSmallAngle = sin( 0 * DEGTORAD) ;
|
||||
const double dSinSmallAngle = sin( 0.5 * DEGTORAD) ;
|
||||
for ( int i = 1 ; i < ssize( vPt5ax) ; ++ i) {
|
||||
// precedente
|
||||
int j = i - 1 ;
|
||||
@@ -160,7 +151,10 @@ AddPointsOnCorners( PNT5AXVECTOR& vPt5ax)
|
||||
// guardo se la proiezione il tratto successivo, lungo la normale precedente + maggiore di un angolo minimo ( angolo interno smooth)
|
||||
Vector3d vtDirNext = vPt5ax[i].ptP - vPt5ax[j].ptP ;
|
||||
vtDirNext.Normalize() ;
|
||||
if ( vtDirNext * vPt5ax[j].vtDir1 > dSinSmallAngle) {
|
||||
double dProj1 = vtDirNext * vPt5ax[j].vtDir1 ;
|
||||
double dProj2 = ( - vtDirNext) * vPt5ax[i].vtDir1 ;
|
||||
|
||||
if ( ( abs( dProj1) > abs( dProj2) ? dProj1 > dSinSmallAngle : dProj2 > dSinSmallAngle)) {
|
||||
// se concavo senza spigolo netto segnalo zona concava smooth
|
||||
vPt5ax[i].nFlag = P5AX_SMOOTH_CONC ;
|
||||
}
|
||||
@@ -382,7 +376,7 @@ ProjectPointOnSurf( const Point3d& ptP, const CISURFPVECTOR& vpSurf, double dPar
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf,
|
||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax, bool bNormOrTang)
|
||||
{
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
@@ -402,16 +396,47 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf,
|
||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie secondo la direzione di minima distanza
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
double dPar, dParNext ;
|
||||
Point3d ptP, ptPNext ;
|
||||
Vector3d vtDirPrev = V_INVALID ;
|
||||
if ( PL.IsClosed()) {
|
||||
Point3d pt1, pt2 ;
|
||||
PL.GetLastLine( pt1, pt2) ;
|
||||
vtDirPrev = pt2 - pt1 ;
|
||||
}
|
||||
bool bFound = PL.GetFirstULine( &dPar, &ptP, &dParNext, &ptPNext) ;
|
||||
Vector3d vtFirst = ptPNext - ptP ;
|
||||
bool bClosed = PL.IsClosed() ;
|
||||
bool bLast = false ;
|
||||
while ( bFound) {
|
||||
// se trovo proiezione, la salvo
|
||||
Point5ax Pt5ax ;
|
||||
if ( ProjectPointOnSurf( ptP, vpSurf, dPar, Pt5ax))
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
// passo al successivo
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
// se richiesta la tangente anziché la normale allora modifico il vettore associato al punto
|
||||
Vector3d vtDir ;
|
||||
if ( ! bNormOrTang) {
|
||||
Vector3d vtNorm = vPt5ax.back().vtDir1 ;
|
||||
if ( ! bLast)
|
||||
vtDir = ptPNext - ptP ;
|
||||
else if ( bClosed)
|
||||
vtDir = vtFirst ;
|
||||
else
|
||||
vtDir = vtDirPrev ;
|
||||
vtDirPrev = vtDir ;
|
||||
if ( vtDirPrev.IsValid())
|
||||
vtDir = Media( vtDir, vtDirPrev) ;
|
||||
Vector3d vtTang = vtDir ^ vtNorm ; vtTang.Normalize() ;
|
||||
vPt5ax.back().vtDir1 = vtTang ;
|
||||
vPt5ax.back().vtDir2 = vtTang ;
|
||||
}
|
||||
// passo al successivo
|
||||
bFound = PL.GetNextULine( &dPar, &ptP, &dParNext, &ptPNext) ;
|
||||
// se sono arrivato alla fine aggiungo l'ultimo punto
|
||||
if ( ! bFound && ! bLast) {
|
||||
bLast = true ;
|
||||
bFound = true ;
|
||||
}
|
||||
}
|
||||
|
||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
||||
|
||||
@@ -29,11 +29,24 @@
|
||||
#include "/EgtDev/Include/EGkRotationXplaneFrame.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkProjectCurveSurf.h"
|
||||
#include "/EgtDev/Include/EGkOffsetCurve3d.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <future>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
#define SAVEEXTEND 0
|
||||
|
||||
#if SAVEEXTEND
|
||||
vector<IGeoObj*> vGeo ;
|
||||
vector<vector<IGeoObj*>> vvGeo ;
|
||||
#include "/EgtDev/Include/EGkColor.h"
|
||||
vector<Color> vCol ;
|
||||
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||
#include "/EgtDev/Include/EGkGeoVector3d.h"
|
||||
#endif
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// costanti per SurfTmRectSwept
|
||||
@@ -2135,3 +2148,102 @@ GetSurfTriMeshRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, do
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfExtension( const ISurfTriMesh* pSrfTM, double dExtLen, int nLoop, int nSubCrv, int nType, double dLinTol)
|
||||
{
|
||||
// controlli sui parametri in input
|
||||
if ( pSrfTM == nullptr || nLoop < 0 || nSubCrv < -1)
|
||||
return nullptr ;
|
||||
|
||||
POLYLINEVECTOR vLoops ;
|
||||
if ( ! pSrfTM->GetLoops( vLoops))
|
||||
return nullptr ;
|
||||
PtrOwner<ICurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( ! pLoop->FromPolyLine( vLoops[nLoop]) || nSubCrv >= pLoop->GetCurveCount())
|
||||
return nullptr ;
|
||||
|
||||
// ricavo il tratto di bordo da estendere, con le tangenti della superficie
|
||||
PtrOwner<ICurve> pEdge ;
|
||||
if ( nSubCrv == - 1)
|
||||
pEdge.Set( pLoop) ;
|
||||
else
|
||||
pEdge.Set( pLoop->GetCurve( nSubCrv)->Clone()) ;
|
||||
|
||||
double dMaxLen = 2.5 ;
|
||||
PNT5AXVECTOR vPnt5Ax ;
|
||||
CISURFPVECTOR vSurf ; vSurf.push_back( pSrfTM) ;
|
||||
bool bClosed = pEdge->IsClosed() ;
|
||||
ProjectCurveOnSurf( *pEdge, vSurf, dLinTol, dMaxLen, true, vPnt5Ax, false) ;
|
||||
//PolyLine PL ;
|
||||
//VCT3DVECTOR vOffDir ;
|
||||
//bool bClosed = pEdge->IsClosed() ;
|
||||
/////////// versione con calcolo della tangente
|
||||
//for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) {
|
||||
// PL.AddUPoint( i, vPnt5Ax[i].ptP) ;
|
||||
// Vector3d vtDir ;
|
||||
// if ( ( i == 0 || i == ssize( vPnt5Ax) - 1) && bClosed)
|
||||
// vtDir = Media( vPnt5Ax.end()[-1].ptP - vPnt5Ax.end()[-2].ptP, vPnt5Ax[1].ptP - vPnt5Ax[0].ptP) ;
|
||||
// else if ( i > 0 && i < ssize( vPnt5Ax) - 1)
|
||||
// vtDir = Media( vPnt5Ax[i].ptP - vPnt5Ax[i-1].ptP, vPnt5Ax[i+1].ptP - vPnt5Ax[i].ptP) ;
|
||||
// else if ( i < ssize( vPnt5Ax) - 1)
|
||||
// vtDir = vPnt5Ax[i+1].ptP - vPnt5Ax[i].ptP ;
|
||||
// else
|
||||
// vtDir = vPnt5Ax[i].ptP - vPnt5Ax[i-1].ptP ;
|
||||
// Vector3d& vtN = vPnt5Ax[i].vtDir1 ;
|
||||
// Vector3d vtOffDir = vtDir ^ vtN ; vtOffDir.Normalize() ;
|
||||
// vOffDir.push_back( vtOffDir) ;
|
||||
//}
|
||||
|
||||
//////////// qui la tangente è già stata calcolata da ProjectCurveOnSurf
|
||||
//for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) {
|
||||
// PL.AddUPoint( i, vPnt5Ax[i].ptP) ;
|
||||
// vOffDir.push_back( vPnt5Ax[i].vtDir1) ;
|
||||
//}
|
||||
|
||||
OffsetCurve3d off3d ;
|
||||
if ( ! off3d.Make( vPnt5Ax, dExtLen, nType))
|
||||
return nullptr ;
|
||||
|
||||
PtrOwner<ICurveComposite> pOffEdge( CreateBasicCurveComposite()) ;
|
||||
for ( int i = 0 ; i < off3d.GetCurveCount() ; ++i) {
|
||||
if ( ! pOffEdge->AddCurve( off3d.GetLongerCurve()))
|
||||
return nullptr ;
|
||||
}
|
||||
#if SAVEEXTEND
|
||||
vvGeo.clear() ;
|
||||
vCol.clear() ;
|
||||
vvGeo.emplace_back() ;
|
||||
vvGeo.back().push_back( pEdge->Clone()) ;
|
||||
vvGeo.back().push_back( pOffEdge->Clone()) ;
|
||||
vCol.push_back( AQUA) ;
|
||||
vvGeo.emplace_back() ;
|
||||
for ( int i = 0 ; i < ssize( vOffDir) ; ++i) {
|
||||
IGeoVector3d* pGV = CreateGeoVector3d() ;
|
||||
pGV->Set( vOffDir[i] * dExtLen, vPnt5Ax[i].ptP) ;
|
||||
vvGeo.back().push_back( pGV) ;
|
||||
}
|
||||
vCol.push_back( LIME) ;
|
||||
SaveGeoObj( vvGeo, vCol, "C:\\Temp\\curve offset 3d\\surfExtend_insight.nge") ;
|
||||
|
||||
vGeo.clear() ;
|
||||
vCol.clear() ;
|
||||
for ( int i = 1 ; i < ssize( vPnt5Ax) ; ++i) {
|
||||
ICurveLine* pCL = CreateBasicCurveLine() ;
|
||||
pCL->Set( vPnt5Ax[i-1].ptP, vPnt5Ax[i].ptP) ;
|
||||
vGeo.push_back( pCL) ;
|
||||
if ( vPnt5Ax[i].nFlag == 6)
|
||||
vCol.push_back( GREEN) ;
|
||||
else if ( vPnt5Ax[i].nFlag == 2)
|
||||
vCol.push_back( RED) ;
|
||||
else
|
||||
vCol.push_back( PURPLE) ;
|
||||
}
|
||||
SaveGeoObj( vGeo, vCol, "C:\\Temp\\curve offset 3d\\surfExtend_con-cvx.nge") ;
|
||||
#endif
|
||||
|
||||
PtrOwner<ISurfTriMesh> pSurfExt( GetSurfTriMeshRuled( pEdge, pOffEdge, ISurfTriMesh::RuledType::RLT_MINDIST, dLinTol)) ;
|
||||
|
||||
return Release( pSurfExt) ;
|
||||
}
|
||||
Reference in New Issue
Block a user