EgtGeomKernel :
- correzioni e migliorie all'offset3d e SurfExtend.
This commit is contained in:
+67
-115
@@ -83,35 +83,6 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
||||
return false ;
|
||||
}
|
||||
|
||||
// identifico le zone circostanti un angolo interno
|
||||
for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) {
|
||||
if ( vFlag[i] == OffsetCurve3d::AngType::ANG_CONC) {
|
||||
// scorro indietro e avanti flaggando i tratti da controllare
|
||||
int nPrev = i - 1 ;
|
||||
if ( nPrev < 0)
|
||||
nPrev = ssize( vPnt5Ax) - 1;
|
||||
int nNext = i + 1 ;
|
||||
if ( nNext >= ssize( vPnt5Ax))
|
||||
nNext = 0 ;
|
||||
double dAng = acos( vPnt5Ax[nPrev].vtDir1 * vPnt5Ax[nNext].vtDir1) ;
|
||||
double dDistAngConc = dOffDist * tan( dAng / 2) ;
|
||||
int c = nPrev ;
|
||||
while ( c > 0 && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) {
|
||||
vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ;
|
||||
--c ;
|
||||
}
|
||||
vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ;
|
||||
// scorro in avanti
|
||||
c = nNext ;
|
||||
while ( c < ssize( vPnt5Ax) && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) {
|
||||
vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ;
|
||||
++c ;
|
||||
}
|
||||
vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ;
|
||||
i = c ;
|
||||
}
|
||||
}
|
||||
|
||||
PtrOwner<CurveComposite> pCrv( CreateBasicCurveComposite()) ;
|
||||
if ( ! pCrv->FromPolyLine( PL))
|
||||
return false ;
|
||||
@@ -158,6 +129,47 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
||||
|
||||
bool bClosed = pCrv->IsClosed() ;
|
||||
|
||||
// identifico le zone circostanti un angolo interno
|
||||
for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) {
|
||||
if ( vFlag[i] == OffsetCurve3d::AngType::ANG_CONC) {
|
||||
// scorro indietro e avanti flaggando i tratti da controllare
|
||||
int nPrev = i - 1 ;
|
||||
if ( nPrev < 0)
|
||||
nPrev = ssize( vPnt5Ax) - 1;
|
||||
int nNext = i + 1 ;
|
||||
if ( nNext >= ssize( vPnt5Ax))
|
||||
nNext = 0 ;
|
||||
double dAng = acos( vPnt5Ax[nPrev].vtDir1 * vPnt5Ax[nNext].vtDir1) * RADTODEG ;
|
||||
double dDistAngConc = dOffDist * tan( ( dAng / 2) * DEGTORAD) ;
|
||||
int c = nPrev ;
|
||||
while ( Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) {
|
||||
vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ;
|
||||
--c ;
|
||||
if ( c < 0) {
|
||||
if ( bClosed)
|
||||
c = ssize( vPnt5Ax) - 1 ;
|
||||
else
|
||||
break ;
|
||||
}
|
||||
}
|
||||
vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ;
|
||||
// scorro in avanti
|
||||
c = nNext ;
|
||||
while ( c < ssize( vPnt5Ax) - 1 && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) {
|
||||
vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ;
|
||||
++c ;
|
||||
if ( c == ssize( vPnt5Ax) - 1) {
|
||||
if ( bClosed)
|
||||
c = 0 ;
|
||||
else
|
||||
break ;
|
||||
}
|
||||
}
|
||||
vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ;
|
||||
i = c ;
|
||||
}
|
||||
}
|
||||
|
||||
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 &&
|
||||
@@ -218,10 +230,10 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
||||
vtTang.Normalize() ;
|
||||
Vector3d vtCorr = vtOffDir ;
|
||||
double dCorrK = 1 ;
|
||||
if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CONC) {
|
||||
double dHalfAlfa = acos( vtTang * vtTangPrev) ;
|
||||
dCorrK = 1 / sin( 90 - dHalfAlfa) ;
|
||||
}
|
||||
//if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CONC) {
|
||||
// double dHalfAlfa = acos( vtTang * vtTangPrev) * RADTODEG ;
|
||||
// dCorrK = 1 / sin( ( 90 - dHalfAlfa) * DEGTORAD) ;
|
||||
//}
|
||||
|
||||
Point3d ptP ;
|
||||
if ( pCrvCurr != nullptr)
|
||||
@@ -250,30 +262,6 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
||||
if ( ! vtAng.IsSmall() && vtAng.Normalize())
|
||||
bPlanarConcCvex = abs( vtAng * vOffDir[nCurr]) < COS_ANG_MAX_PLANAR ;
|
||||
|
||||
//// se punto di angolo interno di fianco, elimino eventuali movimenti precedenti invertiti
|
||||
//if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CVEX == 3) {
|
||||
// local nLastId = EgtGetLastInGroup( nClPathId)
|
||||
// while nLastId do
|
||||
// local vtMlast = ptP - EgtEP( nLastId, GDB_ID.ROOT) ; vtMlast:normalize()
|
||||
// if vtMlast * vtGpre < 0.5 then
|
||||
// ptPpre = EgtSP( nLastId, GDB_ID.ROOT)
|
||||
// EgtErase( nLastId)
|
||||
// else
|
||||
// break
|
||||
// end
|
||||
// nLastId = EgtGetLastInGroup( nClPathId)
|
||||
// end
|
||||
//}
|
||||
|
||||
//// se appena dopo angolo interno di fianco, verifico se da aggiungere
|
||||
//bool bToAdd = true
|
||||
//if ( nFlpre == 3 and abs( dSideAng) > GEO.EPS_ANG_SMALL) {
|
||||
// local vtMove = ptP - ptPpre ; vtMove:normalize()
|
||||
// if vtMove * vtTang < 0.5 then
|
||||
// bToAdd = false
|
||||
// end
|
||||
//}
|
||||
|
||||
if ( ! bCheckingClosure) {
|
||||
Vector3d vtDirCurrOff = ptP - ptPrev ; vtDirCurrOff.Normalize() ;
|
||||
double dProj = 1 ;
|
||||
@@ -376,21 +364,8 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
|
||||
|
||||
return true ;
|
||||
|
||||
|
||||
// raccordi
|
||||
|
||||
// angoli interni
|
||||
|
||||
// angoli esterni
|
||||
|
||||
// auto intersezioni
|
||||
|
||||
//// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi
|
||||
|
||||
//// ottavo passo : concateno i percorsi risultanti (senza cambiare verso)
|
||||
|
||||
//// nono passo : se con smusso o estensione, sostituisco i fillet con questi
|
||||
|
||||
//// ordino le curve in ordine decrescente di lunghezza
|
||||
//if ( m_CrvLst.size() > 1) {
|
||||
// for ( auto pCrv : m_CrvLst) {
|
||||
@@ -467,18 +442,11 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
|
||||
const double dLinTol = 10 * EPS_SMALL ;
|
||||
for ( int i = 0 ; i < ssize( vOffsetCrvs) ; ++i) {
|
||||
int nFlag = vOffsetCrvs[i].nFlag ;
|
||||
if ( nFlag == OffsetCurve3d::AngType::ANG_SMOOTH_CONC || nFlag == OffsetCurve3d::AngType::ANG_BEFORE_CONC) {
|
||||
// considero tutt le zone concave
|
||||
if ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) {
|
||||
// scorro i prossimi finchè trovo la fine della zona concava
|
||||
INTVECTOR vLines ;
|
||||
while ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) {
|
||||
vLines.push_back( i) ;
|
||||
++i ;
|
||||
if ( i < ssize( vOffsetCrvs))
|
||||
nFlag = vOffsetCrvs[i].nFlag ;
|
||||
else
|
||||
nFlag = OffsetCurve3d::AngType::ANG_STR ;
|
||||
}
|
||||
// controllo se devo considerare anche tratti prima dello start
|
||||
INTVECTOR vLines ;
|
||||
if ( i == 0) {
|
||||
INTVECTOR vLinesAdd ;
|
||||
int c = ssize( vOffsetCrvs) - 1 ;
|
||||
@@ -489,9 +457,24 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
|
||||
if ( c > 0)
|
||||
nFlag = vOffsetCrvs[c].nFlag ;
|
||||
}
|
||||
vLinesAdd.insert( vLinesAdd.end(), vLines.begin(), vLines.end()) ;
|
||||
swap( vLinesAdd, vLines) ;
|
||||
// inserisco il vettore al contrario, in modo che sia in ordine crescente
|
||||
vLines.insert( vLines.end(), vLinesAdd.rbegin(), vLinesAdd.rend()) ;
|
||||
}
|
||||
bool bDone = false ;
|
||||
nFlag = vOffsetCrvs[i].nFlag ;
|
||||
while ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) {
|
||||
vLines.push_back( i) ;
|
||||
++i ;
|
||||
if ( i < ssize( vOffsetCrvs))
|
||||
nFlag = vOffsetCrvs[i].nFlag ;
|
||||
else {
|
||||
bDone = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
// se sto ricominciando, esco dal for ( il tratto finale è già stato considerato insieme al tratto iniziale)
|
||||
if ( bDone)
|
||||
break ;
|
||||
CYLVECT vCyl ;
|
||||
// creo un cilindro della dimensione del raggio
|
||||
for ( int j = 0 ; j < ssize( vLines) ; ++j) {
|
||||
@@ -501,7 +484,7 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
|
||||
Point3d ptStart, ptEnd ;
|
||||
pSubCrv->GetStartPoint( ptStart) ;
|
||||
pSubCrv->GetEndPoint( ptEnd) ;
|
||||
////////// cilindri con asse sul parent
|
||||
// cilindri con asse sul parent
|
||||
Vector3d vtHeight = ptEnd - ptStart ;
|
||||
double dHeight = vtHeight.Len() ;
|
||||
vtHeight.Normalize() ;
|
||||
@@ -512,23 +495,6 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
|
||||
vGeo.push_back( pSurfTm) ;
|
||||
vCol.push_back( LGRAY) ;
|
||||
#endif
|
||||
|
||||
// //// cilindri con la direz offset
|
||||
// Point3d ptOffEnd ; vOffsetCrvs[vLines[j]].pCrv->GetEndPoint( ptOffEnd) ;
|
||||
// Vector3d vtOff = ptOffEnd - ptEnd ; vtOff.Normalize() ;
|
||||
// Vector3d vtHeight = ptEnd - ptStart ;
|
||||
// double dHeight = vtHeight.Len() ;
|
||||
// Vector3d vtNewAxis = OrthoCompo( vtHeight, vtOff) ;
|
||||
// vtHeight.Normalize() ;
|
||||
// vtNewAxis.Normalize() ;
|
||||
// Point3d ptStartCyl = ptEnd -vtNewAxis * dHeight ;
|
||||
// vCyl.emplace_back( ptStartCyl, vtNewAxis, dHeight, dRad, dLinTol) ;
|
||||
//#if SAVECYL
|
||||
// CurveArc ca ; ca.Set( vCyl.back().frCyl.Orig(), vCyl.back().frCyl.VersZ(), dRad) ;
|
||||
// ISurfTriMesh* pSurfTm = GetSurfTriMeshByExtrusion( &ca, vCyl.back().frCyl.VersZ() * dHeight, false, 2 * EPS_SMALL) ;
|
||||
// vGeo.push_back( pSurfTm) ;
|
||||
// vCol.push_back( LGRAY) ;
|
||||
//#endif
|
||||
}
|
||||
|
||||
// controllo l'end di ogni linea per verificare se sta nel cilindro definito da uno degli altri tratti
|
||||
@@ -558,16 +524,7 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
|
||||
bErasedSomePart = true ;
|
||||
if ( ! bStartInsideCyl)
|
||||
bCheckStart = true ;
|
||||
//// se avevo un'interruzione nella zona da modificare, la colmo
|
||||
//if ( ! vInters.empty() && vInters.back().first != vLines[j-1]) {
|
||||
// // aggiungo tutti i precedenti che mancano
|
||||
// int z = vInters.back().second ;
|
||||
// for ( int h = vInters.back().first + 1 ; h < vLines[j] ; ++h) {
|
||||
// vInters.emplace_back( h, z) ;
|
||||
// vEditInfo.pop_back() ;
|
||||
// ++z ;
|
||||
// }
|
||||
//}
|
||||
|
||||
if ( vEditZones.empty() || vEditZones.back().back().first != vLines[j-1])
|
||||
vEditZones.emplace_back() ;
|
||||
vEditZones.back().emplace_back( vLines[j], j) ;
|
||||
@@ -584,11 +541,6 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
|
||||
}
|
||||
}
|
||||
if ( bErasedSomePart) {
|
||||
//// controllo che effettivamente tutti i tratti cancellati siano consecutivi
|
||||
//for ( int j = 1 ; j < ssize( vInters) ; ++j) {
|
||||
// if ( vInters[j].first != vInters[j-1].first + 1)
|
||||
// return false ;
|
||||
//}
|
||||
// calcolo le intersezioni effettive del primo e ultimo tratto cancellati con i cilindri che li hanno cancellati
|
||||
for ( int z = 0 ; z < ssize( vEditZones) ; ++z) {
|
||||
INTINTVECTOR& vInters = vEditZones[z] ;
|
||||
|
||||
+11
-3
@@ -13,6 +13,7 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include <cmath>
|
||||
#include "SurfTriMesh.h"
|
||||
#include "SurfBezier.h"
|
||||
#include "GeoConst.h"
|
||||
@@ -1292,17 +1293,24 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf,
|
||||
Vector3d vtNormPrev = V_INVALID ;
|
||||
Point3d ptPrev ;
|
||||
bool bFirst = true ;
|
||||
const ICurveComposite* pCC = GetCurveComposite( &crCrv) ;
|
||||
while ( bFound) {
|
||||
// se trovo proiezione, la salvo
|
||||
Point5ax Pt5ax ;
|
||||
Pt5ax.ptP = ptP ;
|
||||
Pt5ax.dPar = dPar ;
|
||||
int nTria = int( crCrv.GetTempParam( dPar)) ;
|
||||
double dDecimal ;
|
||||
int nCrv = int( modf( dPar, &dDecimal) == 0.0 ? dPar - 1 : dPar) ;
|
||||
if ( nCrv < 0)
|
||||
nCrv = 0 ;
|
||||
int nTria ; pCC->GetCurveTempProp( nCrv, nTria, 0) ;
|
||||
Triangle3d trTria ; pSurf.GetTriangle( nTria, trTria) ;
|
||||
Pt5ax.vtDir1 = trTria.GetN() ;
|
||||
Pt5ax.vtDir2 = Pt5ax.vtDir1 ;
|
||||
Pt5ax.vtDirU = V_NULL ;
|
||||
Pt5ax.vtDirV = V_NULL ;
|
||||
Pt5ax.nFlag = P5AX_STD ;
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
|
||||
/*if ( ProjectPointOnSurf( ptP, vpSurf, dPar, Pt5ax))
|
||||
vPt5ax.emplace_back( Pt5ax) ;*/
|
||||
@@ -1356,9 +1364,9 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf,
|
||||
vtDir = vtDirPrev ;
|
||||
// in caso sia stato superato l'angolo limite dò priorità alla direzione precedente
|
||||
if ( vtDirPrev.IsValid() && (! bFirst || ( bFirst && bClosed))) {
|
||||
double dProj = vtDir * vtDirPrev ;
|
||||
double dProj = vtDirNext * vtDirPrev ;
|
||||
if ( dProj > COS_ANG_MAX_CORNER)
|
||||
vtDir = Media( vtDir, vtDirPrev) ;
|
||||
vtDir = Media( vtDirNext, vtDirPrev) ;
|
||||
}
|
||||
vtDirPrev = vtDirNext ;
|
||||
Vector3d vtTang = vtDir ^ vtNorm ; vtTang.Normalize() ;
|
||||
|
||||
+1
-1
@@ -2171,7 +2171,7 @@ GetSurfExtension( const ISurfTriMesh* pSrfTM, double dExtLen, int nLoop, int nSu
|
||||
PL.GetFirstUPoint( &dPar, &pt) ;
|
||||
for ( int i = 0 ; i < pLoop->GetCurveCount() ; ++i) {
|
||||
PL.GetNextUPoint( &dPar, &pt) ;
|
||||
pLoop->SetTempProp( i, dPar) ;
|
||||
pLoop->SetCurveTempProp( i, int( dPar)) ;
|
||||
}
|
||||
|
||||
// ricavo il tratto di bordo da estendere, con le tangenti della superficie
|
||||
|
||||
Reference in New Issue
Block a user