Compare commits

...

16 Commits

Author SHA1 Message Date
Riccardo Elitropi 8538bc2d30 Merge commit 'e490c173e84ed5bf576888ac4bc5f023c49680f7' into VmillAdditivo 2024-04-30 08:36:48 +02:00
Daniele Bariletti e490c173e8 EgtGeomKernel :
- svincolata la funzione GetSingleEdge della SurfBezier dalla creazione della trimesh.
2024-04-29 17:46:30 +02:00
Daniele Bariletti 7e165a6dea EgtGeomKernel :
- eliminati dei memory leaks.
2024-04-29 17:40:17 +02:00
Daniele Bariletti 49ff6e79a8 EgtGeomKernel :
- correzione nella gestione della conversione delle curve/superfici NURBS.
2024-04-29 17:20:30 +02:00
Daniele Bariletti b23df89cd3 EgtGeomKernel :
- tolto header di debug.
2024-04-24 10:48:58 +02:00
Daniele Bariletti cf9737a48e Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel 2024-04-24 10:47:54 +02:00
Daniele Bariletti ae52115bda EgtGeomKernel :
- aggiunto il contro OFFSET alla SetTrimRegion delle Bezier
- aggiunte funzioni varie al tree delle Bezier.
2024-04-24 10:47:50 +02:00
Riccardo Elitropi c0f7eb6727 EgtGeomKernel :
- piccola correzione booleane TriMesh.
2024-04-24 09:26:51 +02:00
Riccardo Elitropi faa2004c29 EgtGeomKernel :
- integrate modifiche vMill additivo dal ramo TempForVmill.
2024-04-22 13:21:37 +02:00
Dario Sassi c9a59dc5ea Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel 2024-04-22 10:50:40 +02:00
Dario Sassi aaaf951990 EgtGeomKernel :
- aggiunti alcuni controlli sulla validità dei parametri in Collision Avoid.
2024-04-22 10:49:34 +02:00
Daniele Bariletti cc263089ca EgtGeomKernel :
- aggiunta gestione ulteriore delle curve nurbs periodiche da formato .stp.
2024-04-22 09:15:49 +02:00
Daniele Bariletti d99b8f4c86 EgtGeomKernel :
- correzione alla conversione di curve NURBS.
- modifica del parametro per il metodo IsPlanar di SurfBezier.
2024-04-18 11:04:34 +02:00
Daniele Bariletti f5e5441469 EgtGeomKernel :
- aggiunto il metodo IsPlanar per la SurfBezier.
2024-04-17 16:00:30 +02:00
Daniele Bariletti 4206a4822f EgtGeomKernel :
- funzione CalcPoles chiamata direttamente all'inizio della funzione Cut.
2024-04-17 15:16:23 +02:00
Daniele Bariletti 788a5bc4eb EgtGeomKernel :
- correzioni nella gestione dei trim delle superfici di Bezier.
- correzioni varie alle superfici di Bezier.
2024-04-17 14:52:07 +02:00
14 changed files with 1747 additions and 394 deletions
+6
View File
@@ -104,6 +104,9 @@ CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Ve
// Se utensile non definito, errore
if ( m_Tool.GetType() == Tool::UNDEF)
return false ;
// Se direzioni non definite, errore
if ( vtDir.IsSmall() || vtMove.IsSmall())
return false ;
// Imposto il riferimento di movimento
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
m_frMove.Set( ORIG, vtMove, vtDir) ;
@@ -122,6 +125,9 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
// Se utensile non definito, errore
if ( m_Tool.GetType() == Tool::UNDEF)
return false ;
// Se direzioni non definite, errore
if ( vtDir.IsSmall() || vtMove.IsSmall())
return false ;
// Se lista vuota, non devo fare alcunché
if ( lPntM.empty())
return true ;
+45 -3
View File
@@ -525,6 +525,7 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
// se periodica
if ( cnData.bPeriodic || ! cnData.bClamped) {
// se la curva è peridica verifco che effettivamente ci sia un numero di punti ripetituti uguale al grado della curva
// wrap della curva su se stessa
if ( cnData.bPeriodic ) {
bool bRepetead = true ;
for ( int i = 0 ; i < cnData.nDeg ; ++i) {
@@ -534,6 +535,8 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
}
}
if ( ! bRepetead){
// salvo il vettore dei nodi in caso mi accorga di avere tra le mani una curva unclamped
DBLVECTOR vU = cnData.vU ;
// se il primo e l'ultimo punto non coincidono allora aggiungo il primo punto in fondo al vettore dei punti di controllo
if ( ! AreSamePointApprox( cnData.vCP[0], cnData.vCP.back()) ) {
cnData.vCP.push_back( cnData.vCP[0]) ;
@@ -544,7 +547,36 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
if ( int( cnData.vU.size()) != int(cnData.vCP.size()) + cnData.nDeg - 1) {
// devo poi anche togliere i nodi di troppo // presuppongo che la convenzione sia che i nodi di troppo sono alla fine del vettore dei nodi
cnData.vU = DBLVECTOR( cnData.vU.begin(), cnData.vU.end() - cnData.nDeg) ;
// controlloeventualmente anche i nodi extra
// controllo eventualmente anche i nodi extra
// se ne ho due in più ne tolgo uno in cima e uno in fondo
if ( cnData.vU.size() == int( cnData.vCP.size()) + cnData.nDeg + 1 ) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere
cnData.vU = vector<double>( cnData.vU.begin() + 1, cnData.vU.end() - 1) ;
// se ne ho solo uno in più lo tolgo in cima
else if ( cnData.vU.size() == int( cnData.vCP.size()) + cnData.nDeg)
cnData.vU = vector<double>( cnData.vU.begin() + 1, cnData.vU.end()) ;
}
// controllo se il vettore dei nodi ha la giusta molteplicità all'inizio e alla fine, sennò ha comunque bisogno di essere resa non periodica
double dU0 = cnData.vU[0] ;
double dULast = cnData.vU.back() ;
bool bSame = true ;
for ( int i = 1 ; i < cnData.nDeg ; ++i ) {
bSame = bSame && abs(cnData.vU[i] - dU0) < EPS_SMALL ;
bSame = bSame && abs(cnData.vU.end()[-( i+ 1)] - dULast) < EPS_SMALL ;
}
if ( bSame) {
cnData.bPeriodic = false ;
return true ;
}
else {
// aggiungo i punti ripetuti ( il primo l'ho già aggiunto)
for ( int i = 1 ; i < cnData.nDeg ; ++i ) {
cnData.vCP.push_back( cnData.vCP[i]) ;
if ( cnData.bRat)
cnData.vW.push_back( cnData.vW[i]) ;
}
// recupero il vettore dei nodi
cnData.vU = vU ;
// verifico se ho nodi extra
// se ne ho due in più ne tolgo uno in cima e uno in fondo
if ( cnData.vU.size() == int( cnData.vCP.size()) + cnData.nDeg + 1 ) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere
cnData.vU = vector<double>( cnData.vU.begin() + 1, cnData.vU.end() - 1) ;
@@ -552,11 +584,21 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
else if ( cnData.vU.size() == int( cnData.vCP.size()) + cnData.nDeg)
cnData.vU = vector<double>( cnData.vU.begin() + 1, cnData.vU.end()) ;
}
cnData.bPeriodic = false ;
return true ;
}
}
// qui aggiungo un controllo se la curva è collassata in un punto ( ho un polo), lascio stare
bool bCollapsed = true ;
Point3d ptFirst = cnData.vCP.front() ;
for( int i = 1 ; i < int( cnData.vCP.size()) ; ++i) {
if ( ! AreSamePointApprox( ptFirst, cnData.vCP[i])) {
bCollapsed = false ;
break ;
}
}
if ( bCollapsed)
return false ;
// va trasformata in non-periodica (clamped)
// bisogna aumentare la molteplicità dei nodi u_p-1 e u_(m-p+1) fino ad arrivare al grado della nurbs
// e poi scartare nodi e punti fuori dalla regione clamped ( al di fuori della regione u_p-1 -> u_(m-p+1))
+15 -11
View File
@@ -62,11 +62,12 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
nuCurve.vCP = vPtCtrl ;
nuCurve.vW = vWeCtrl ;
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
NurbsCurveCanonicalize( nuCurve) ;
for ( int i = 0 ; i < snData.nCPU ; ++i) {
snData.mCP[i][j] = nuCurve.vCP[i] ;
if ( NurbsCurveCanonicalize( nuCurve)) { // se NurbsCurveCanonicalize ha restituito false (la curva potrebbe esserre un punto di polo) allora non modifico i punti e il vettore dei nodi della superficie
for ( int i = 0 ; i < snData.nCPU ; ++i) {
snData.mCP[i][j] = nuCurve.vCP[i] ;
}
snData.vU = nuCurve.vU ;
}
snData.vU = nuCurve.vU ;
}
snData.bPeriodicU = false ;
}
@@ -99,11 +100,12 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
nuCurve.vCP = vPtCtrl ;
nuCurve.vW = vWeCtrl ;
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
NurbsCurveCanonicalize( nuCurve) ;
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
snData.mCP[i][j] = nuCurve.vCP[j] ;
if ( NurbsCurveCanonicalize( nuCurve)) { // se NurbsCurveCanonicalize ha restituito false (la curva potrebbe esserre un punto di polo) allora non modifico i punti e il vettore dei nodi della superficie
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
snData.mCP[i][j] = nuCurve.vCP[j] ;
}
snData.vV = nuCurve.vU ;
}
snData.vV = nuCurve.vU ;
}
snData.bPeriodicV = false ;
}
@@ -604,7 +606,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
pSfr_copy->Translate( vtJoin) ;
// se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET
if ( bRetry)
pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_FILLET) ; // OFFSET
pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // OFFSET
if ( pRescaledSfr->IsValid()) {
if ( ! pRescaledSfr->Add( *pSfr_copy))
return false ;
@@ -617,7 +619,8 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
if ( pRescaledSfr->IsValid()) {
if ( bRetry)
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_FILLET) ; //contro OFFSET
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; //contro OFFSET
delete pSfr ;
pSfr = Release( pRescaledSfr) ;
}
}
@@ -628,7 +631,8 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) {
if ( bRetry)
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_FILLET) ; // contro OFFSET
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // contro OFFSET
delete pSfr ;
pSfr = Release( pRescaledSfr) ;
}
+56 -4
View File
@@ -157,6 +157,7 @@ SurfBezier::SetTrimRegion( ISurfFlatRegion& sfrTrimReg, bool bIntersectOrSubtrac
pSfrTrim->Offset( 10* EPS_SMALL, ICurve::OFF_EXTEND) ;
if ( ! pSfrTrim->Intersect( sfrTrimReg) || ! pSfrTrim->IsValid())
return false ;
pSfrTrim->Offset( -10* EPS_SMALL, ICurve::OFF_EXTEND) ;
}
}
// bIntersectOrSubtract == false per ottenere lo spazio parametrico trimmato devo fare la SOTTRAZIONE tra il rettangolo totale e l'area passata
@@ -166,6 +167,7 @@ SurfBezier::SetTrimRegion( ISurfFlatRegion& sfrTrimReg, bool bIntersectOrSubtrac
pSfrTrim->Offset( 10* EPS_SMALL, ICurve::OFF_EXTEND) ;
if ( ! pSfrTrim->Subtract( sfrTrimReg) || ! pSfrTrim->IsValid())
return false ;
pSfrTrim->Offset( -10* EPS_SMALL, ICurve::OFF_EXTEND) ;
}
}
ResetAuxSurf() ;
@@ -1515,7 +1517,10 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
// costruttore della superficie
POLYLINEMATRIX vvPL ;
//POLYLINEVECTOR vPL ; // per usare i polygon basic
Tree Tree( this, true) ;
//Tree Tree( this, true) ;
Tree Tree ;
if ( ! Tree.SetSurf( this, true))
return nullptr ;
BIPNTVECTOR vTrees ;
Tree.GetIndependentTrees( vTrees) ;
bool bTest = false ; // per debug
@@ -1536,7 +1541,8 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
//Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
Tree.BuildTree( dTol, dSideMin) ;
}
Tree.GetPolygons( vvPL) ;
if ( ! Tree.GetPolygons( vvPL))
continue ;
//Tree.GetPolygonsBasic( vPL) ; // per usare i polygon basic
// aggiorno la chiusura della superficie
@@ -1597,7 +1603,9 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
bool
SurfBezier::GetLeaves( vector<tuple<int, Point3d, Point3d>>& vLeaves) const
{
Tree Tree( this, true) ;
Tree Tree ;
if ( ! Tree.SetSurf( this, true))
return false ;
BIPNTVECTOR vTrees ;
Tree.GetIndependentTrees( vTrees) ;
for ( int i = 0 ; i < int( vTrees.size()) ; ++ i) {
@@ -1882,6 +1890,10 @@ SurfBezier::Cut( const Plane3d& plPlane, bool bSaveOnEq)
// le curve 3d le trasformo in curve 2d e le aggiungo alle curve di trim
// accorpo eventuali triangoli adiacenti ed estraggo i loop delle regioni ottenute; questi vengono poi portati in 2d e aggiunti alle curve di trim
// se necessario calcolo i poli
if ( m_vbPole.empty())
CalcPoles() ;
PNTVECTOR vPnt ;
BIPNTVECTOR vBPnt ;
TRIA3DVECTOR vTria ;
@@ -2711,7 +2723,7 @@ SurfBezier::UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d
bool
SurfBezier::CalcPoles( void)
{
// controllo se uno o più lati sono in realtà dei poli
// la funzione identifica se degli edge della superficie non trimmata sono in realtà dei poli
for ( int i = 0 ; i < 4 ; ++i)
m_vbPole.emplace_back( true) ;
// scorro i punti di controllo e vedo subito
@@ -3102,6 +3114,8 @@ SurfBezier::GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge) con
ICurveComposite*
SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
{
if ( m_mCCEdge.size() == 0 && bLineOrBezier)
GetAuxSurf() ;
// questa funzione dà per scontato che la superficie NON sia trimmata
if ( nEdge < 0 || nEdge > 3 || m_bTrimmed)
return nullptr ;
@@ -3195,3 +3209,41 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
}
return pCrvCompo ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::IsPlanar( void) const
{
// costruisco il contorno della superficie unendo gli edge e chiedo se la polyline è piana.
PtrOwner<ICurveComposite> pCCEdge( GetSingleEdge3D( false, 0)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 1)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 2)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 3)) ;
PolyLine plApprox ;
pCCEdge->ApproxWithLines( 0.01, 15, 0, plApprox) ;
Plane3d plPlane ;
if ( ! plApprox.IsFlat( plPlane, 2 * EPS_SMALL))
return false ;
// in questo caso se è grado 1 in U e V e ho un unica Patch allora sono sicuro sia piana
if ( m_nDegU == 1 && m_nSpanU == 1 && m_nDegV == 1 && m_nSpanV == 1) // questa condizione da sola non è sufficiente ( posso avere superfici torte anche se i lati sono segmenti)
return true ;
double dULast ; plApprox.GetLastU( dULast) ;
++ dULast ;
// altrimenti devo verificare anche all'interno della superficie, prendendo dei punti campione
DBLVECTOR vSampling { 0.2, 0.4, 0.6, 0.8} ;
for ( double i : vSampling) {
for ( double j : vSampling) {
Point3d ptBez ;
GetPointD1D2( i * m_nSpanU, j * m_nSpanV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez) ;
if ( plApprox.AddUPoint( dULast, ptBez))
++ dULast ;
}
}
plPlane.Reset() ;
if ( plApprox.IsFlat( plPlane, 2 * EPS_SMALL))
return true ;
// nel dubbio restituisco false
return false ;
}
+3 -2
View File
@@ -130,14 +130,13 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
// funzione per tagliare una superficie di bezier con un piano ( cancello la parte dal lato positivo della normale del piano).
// bSaveOnEq indica se tenere i triangoli (della trimesh associata) che sono sul piano
bool Cut( const Plane3d& plPlane, bool bSaveOnEq = false) override ;
// funzione che calcola se gli edge sono collassati in poli. DEVE ESSERE STATA CHIAMATA PRIMA DI UN CUT
bool CalcPoles( void) override ;
// funzioni per incrementare le coordinate restando dentro lo spazio parametrico
bool IncreaseUV( double& dU, double dx, bool bUOrV, double* dUVCopy = nullptr, bool bModifyOrig = true) const override ;
bool IncreaseUV( Point3d& ptUV, Vector3d vtH , Point3d* ptUVCopy, bool bModifyOrig) const override ;
// funzione che restituisce gli edge della superficie o in forma di linea spezzata o in forma di curva di Bezier
// se la superficie è trimmata restituisce i loop dello spazio parametrico in forma di linee spezzate
bool GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge = -1) const override ;
bool IsPlanar( void) const override ;
public : // IGeoObjRW
int GetNgeId( void) const override ;
@@ -193,6 +192,8 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
// restituisce il singolo edge della superficie non trimmata
ICurveComposite* GetSingleEdge3D( bool bLineOrBezier, int nEdge) const ;
bool UpdateEdgesFromTree( Tree& tr) const ;
// funzione che calcola se gli edge sono collassati in poli
bool CalcPoles( void) ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
+20 -7
View File
@@ -76,10 +76,9 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA
( nLastOpenLoopPoint == 0 && ( Loop1.size() == 2 || Loop2.size() == 2)))
continue ; // la catena aperta non è interna al loop chiuso attuale
// il loop 1 segue sempre la direzione della catena, il loop 2 ha dentro la catena invertita
// Ho sempre che il loop 1 è sempre interno ( la direzione della catena è determinata
// dalla normale dei triangoli che la formano; avendo chimatao la chian senza ammettere inversioni, sono
// curve tutte concordi ) e il loop 2 che è esterno
// il loop 2 segue sempre la direzione della catena, il loop 1 ha dentro la catena invertita
// ( la direzione della catena è determinata dalla normale dei triangoli che la formano;
// avendo chiamato la chain senza ammettere inversioni, sono curve tutte concordi )
bLoopSplitted = true ;
// ricostrusico i due loop mediante concatenazione
Chain cvCounterChain ;
@@ -584,6 +583,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
POLYLINEVECTOR vplPolyVec ;
vplPolyVec.resize( cvBoundClosedLoopVec.size()) ;
for ( int nLoop = 0 ; nLoop < int( vplPolyVec.size()) ; ++ nLoop) {
for ( int nLine = 0 ; nLine < int( cvBoundClosedLoopVec[nLoop].size()) ; ++ nLine)
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][nLine]) ;
@@ -591,7 +591,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
// Assegno ai loop trovati i rispettivi interni
// Assumo che i loop interni a uno dei loop creati fino ad'ora siano tutti sullo stesso livello.
// Il caso generale si risolve con una struttura ad albero in cui il nodi corrispondente a un
// Il caso generale si risolve con una struttura ad albero in cui il nodo corrispondente a un
// loop è figlio del nodo corrispondente al loop che lo contiene.
INTVECTOR vInnerLoop ;
for ( int nCLI = 0 ; nCLI < int( cvClosedChain.size()) ; ++ nCLI) {
@@ -742,6 +742,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
// se ho più loop, essi descrivono un poligono di n-lati
POLYLINEVECTOR vPolygons ;
vPolygons.emplace_back( vplPolyVec[nLoop]) ;
for ( int nL = 0 ; nL < int( vInnerLoop.size()) ; ++ nL) {
// per ognuno di essi, ricavo la PolyLine dai punti
PolyLine CurLoop ;
@@ -955,11 +956,22 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
vPolygons.erase( vPolygons.begin() + i) ;
else
++ i ;
}
bool bCordirectedNormals_intLoop = bCodirectedNormals ;
if ( ! vPolygons.empty()) {
Polygon3d pgPol ;
pgPol.FromPolyLine( vPolygons[0]) ;
// controllo direzioni delle normali
bCordirectedNormals_intLoop = trTria.GetN() * pgPol.GetVersN() > 0. ;
if ( ! bCordirectedNormals_intLoop)
vPolygons[0].Invert() ;
}
if ( Triangulate().MakeAdvanced( vPolygons, vPt, vTr)) {
// Inserisco i nuovi triangoli
for (int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ;
int nNewId[3] = { Surf.AddVertex( vPt[nNewTriaVertId[0]]),
Surf.AddVertex( vPt[nNewTriaVertId[1]]),
@@ -969,7 +981,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
Surf.m_vTria[nNewTriaNum].nETempFlag[0] = 0 ;
Surf.m_vTria[nNewTriaNum].nETempFlag[1] = 0 ;
Surf.m_vTria[nNewTriaNum].nETempFlag[2] = 0 ;
if ( bCodirectedNormals)
if ( bCordirectedNormals_intLoop)
Surf.m_vTria[nNewTriaNum].nTempPart = 1 ;
else
Surf.m_vTria[nNewTriaNum].nTempPart = -1 ;
@@ -1767,6 +1779,7 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
IntersectTriMeshTriangle( SurfB) ;
IdentifyParts() ;
SurfB.IdentifyParts() ;
+83
View File
@@ -580,3 +580,86 @@ Tool::SetChiselTool( const string& sToolName, double dH, double dW, double dTh,
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum)
{
// Impostazioni generali
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
m_nType = UNDEF ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
// verifica sulle minime dimensioni globali
if ( dH < EPS_SMALL || dR < EPS_SMALL || dRC < - EPS_SMALL)
return false ;
m_dHeight = dH ;
m_dRadius = dR ;
m_dRCorner = dRC ;
m_dTipHeight = 0 ;
m_dTipRadius = 0 ;
m_dRefRadius = 0 ;
m_dCutterHeight = dH ;
bool bToolDefined = true ;
double dSquareCornerRadProj = m_dRCorner * m_dRCorner - 0.25 * m_dHeight * m_dHeight ;
// Utensile sfiancato
if ( dSquareCornerRadProj > 0) {
double dCenX = m_dRadius - m_dRCorner ;
double dCylRad = dCenX + sqrt( dSquareCornerRadProj) ;
// Utensile mal definito
if ( dCylRad < EPS_SMALL)
return false ;
// Profilo
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
m_Outline.AddLine( Point3d( dCylRad, 0, 0)) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
CurveArc cvArc ;
cvArc.SetC2P( Point3d( dCenX, - 0.5 * m_dHeight, 0), Point3d( dCylRad, 0, 0), Point3d( dCylRad, - m_dHeight, 0)) ;
m_Outline.AddCurve( cvArc) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
bToolDefined = SetGenTool( sToolName, &m_Outline, nToolNum) ;
}
// Utensile cilindrico con eventuale raggio corner
else {
// Utensile mal definito
if ( m_dRadius - m_dRCorner < 0)
return false ;
// Utensile sferico
else if ( m_dRadius - m_dRCorner < EPS_SMALL)
;
// Raggio corner nullo: cilindro
else if ( m_dRCorner < EPS_SMALL) {
;
}
else {
// Profilo
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
m_Outline.AddLine( Point3d( m_dRadius - m_dRCorner, 0, 0)) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
CurveArc cvArc ;
cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, 0, 0), Point3d( m_dRadius, - m_dRCorner, 0)) ;
m_Outline.AddCurve( cvArc) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0)) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, - m_dHeight, 0)) ;
m_Outline.AddCurve( cvArc) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 4, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
bToolDefined = SetGenTool( sToolName, &m_Outline, nToolNum) ;
}
}
m_nType = ADDITIVE ;
return bToolDefined ;
}
+3 -1
View File
@@ -33,6 +33,7 @@ class Tool
bool SetGenTool( const std::string& sToolName, const ICurveComposite* pToolOutline, int nToolNum) ;
bool SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nToolNum) ;
bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh, int nToolNum) ;
bool SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum) ;
bool SetToolNum( int nToolNum)
{ m_nCurrentNum = nToolNum ; return true ; }
int GetType() const
@@ -70,7 +71,8 @@ class Tool
BULLNOSEMILL = 4, // Naso di toro
CONEMILL = 5, // Con parte terminale conica
MORTISER = 6, // Mortasatrice
CHISEL = 7} ; // Scalpello
CHISEL = 7, // Scalpello
ADDITIVE = 8} ; // Additivo
private :
bool ModifyForCutterHeight( void) ;
+423 -78
View File
@@ -20,12 +20,14 @@
#include "CurveComposite.h"
#include "SurfFlatRegion.h"
#include "IntersLineLine.h"
#include "AdjustLoops.h"
#include "/EgtDev/Include/EGkPolyLine.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkCurve.h"
#include "DistPointCrvComposite.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include <algorithm>
#include <numeric>
using namespace std ;
@@ -39,13 +41,13 @@ Tree::Tree( void)
m_mTree.insert( pair< int, Cell>( -1, cRoot)) ;
}
//----------------------------------------------------------------------------
Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax)
: m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_vbPole( { false, false, false, false}),
m_bSplitPatches( true), m_bTestMode( false)
{
SetSurf( pSrfBz, bSplitPatches, ptMin, ptMax) ;
}
////----------------------------------------------------------------------------
//Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax)
// : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_vbPole( { false, false, false, false}),
// m_bSplitPatches( true), m_bTestMode( false)
//{
// SetSurf( pSrfBz, bSplitPatches, ptMin, ptMax) ;
//}
//----------------------------------------------------------------------------
Tree::~Tree( void)
@@ -63,45 +65,159 @@ Tree::Tree( const Point3d ptBl, const Point3d ptTr)
//----------------------------------------------------------------------------
bool
Tree::LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl) const
Tree::LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const
{
// creo la flat region di trim, quella del parametrico e li interseco
PtrOwner<ISurfFlatRegion> pSfrTrim( GetSurfFlatRegionFromPolyLine( pl)) ;
bool bInverted = false ;
if ( ! pSfrTrim->GetNormVersor().IsZplus()) {
pSfrTrim->Invert() ;
bInverted = true ;
}
PtrOwner<ISurfFlatRegion> pParamTrim( GetSurfFlatRegionRectangle( SBZ_TREG_COEFF * m_nSpanU, SBZ_TREG_COEFF * m_nSpanV)) ;
if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid())
return false ;
// //questo metodo NON VA BENE perchè tiene anche parte dei loop che stanno fuori dal parametrico e quindi il FINDCELL può fallire
//
//// creo la flat region di trim, quella del parametrico e li interseco
//PtrOwner<ISurfFlatRegion> pSfrTrim( GetSurfFlatRegionFromPolyLine( pl)) ;
//bool bInverted = false ;
//if ( ! pSfrTrim->GetNormVersor().IsZplus()) {
// pSfrTrim->Invert() ;
// bInverted = true ;
//}
//PtrOwner<ISurfFlatRegion> pParamTrim( GetSurfFlatRegionRectangle( SBZ_TREG_COEFF * m_nSpanU, SBZ_TREG_COEFF * m_nSpanV)) ;
//if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid()) {
// if ( ! pParamTrim->Offset( 10 * EPS_SMALL, ICurve::OFF_EXTEND))
// return false ;
// if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid())
// return false ;
// if ( ! pParamTrim->Offset( -10 * EPS_SMALL, ICurve::OFF_EXTEND))
// return false ;
//}
// ricostruisco la curva tenendo solo le parti dentro lo spazio parametrico
// devo recuperare la polyline dei bordi dei vari chunk creati
for ( int c = 0 ; c < int( pParamTrim->GetChunkCount()) ; ++c) {
PtrOwner<ICurve> pCrv ( pParamTrim->GetLoop( c, 0)) ;
if ( bInverted)
pCrv->Invert() ;
PolyLine plApprox ;
double dLinTol = 10 * EPS_SMALL, dAngTolDeg = 5 ;
int nType = 0 ;
pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, plApprox) ;
// aggiungo la polyline del chunk
vPl.push_back( plApprox) ;
//// ricostruisco la curva tenendo solo le parti dentro lo spazio parametrico
//// devo recuperare la polyline dei bordi dei vari chunk creati
//for ( int c = 0 ; c < int( pParamTrim->GetChunkCount()) ; ++c) {
// for ( int l = 0 ; l < pParamTrim->GetLoopCount(c) ; ++l) {
// PtrOwner<ICurve> pCrv ( pParamTrim->GetLoop( c, l)) ;
// if ( bInverted)
// pCrv->Invert() ;
// PolyLine plApprox ;
// double dLinTol = 10 * EPS_SMALL, dAngTolDeg = 5 ;
// int nType = 0 ;
// pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, plApprox) ;
// // aggiungo la polyline del chunk
// vPl.push_back( plApprox) ;
// }
//}
//// CON LE CURVE ( INTERSEZIONI CON BORDO PARAMETRICO)
PtrOwner<ICurveComposite> pCCEdge( CreateCurveComposite()) ;
pCCEdge->AddPoint( m_mTree.at(-1).GetTopRight()) ;
pCCEdge->AddLine( m_mTree.at(-1).GetTopLeft()) ;
pCCEdge->AddLine( m_mTree.at(-1).GetBottomLeft()) ;
pCCEdge->AddLine( m_mTree.at(-1).GetBottomRight()) ;
pCCEdge->Close() ;
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
pCC->FromPolyLine( pl) ;
ICURVEPLIST vCrv ;
AdjustLoops( Release( pCC), vCrv, false) ;
if ( vCrv.size() > 1)
VerifyLoopOrientation( vCrv, vbOrientation) ;
for ( auto itCrv = vCrv.begin() ; itCrv != vCrv.end() ; ++itCrv) {
IntersCurveCurve icc( *pCCEdge, *(*itCrv)) ;
CRVCVECTOR vCrvClass ;
ICRVCOMPOPOVECTOR vCC ;
if ( ! icc.GetCurveClassification( 1, 0.01, vCrvClass))
return false ; // se non riesco a calcolare la classificazione potrei provare a ricostruire a mano usando le intersezioni trovate
int nLast = 0 ;
if ( vCrvClass.size() > 1) {
for ( int i = 0 ; i < int( vCrvClass.size()) ; ++i) {
if ( vCrvClass[i].nClass != CRVC_OUT) {
// se continua la curva precedente allora la giunta
if ( vCC.size() != 0 && vCrvClass[i].dParS == vCrvClass[nLast].dParE)
vCC.back()->AddCurve( (*itCrv)->CopyParamRange( vCrvClass[i].dParS, vCrvClass[i].dParE)) ;
// sennò creo una nuova curva
else
vCC.emplace_back( GetCurveComposite( (*itCrv)->CopyParamRange( vCrvClass[i].dParS, vCrvClass[i].dParE))) ;
nLast = i ;
}
}
POLYLINEVECTOR vPL ;
// qui devo ricostruire la curva con i pezzi da tenere
for ( int i = 0 ; i < int( vCC.size()) ; ++i) {
PolyLine plApprox ;
vCC[i]->ApproxWithLines( 0.01,15, 0, plApprox) ;
vPL.push_back( plApprox) ;
}
PolyLine plNew ;
// ricostruzione col bordo
CloseOpenCuts( vPL, plNew) ;
vPl.push_back( plNew) ;
}
else {
PolyLine plApprox ; (*itCrv)->ApproxWithLines( 0.01, 15, 0, plApprox) ;
vPl.push_back( plApprox) ;
}
}
return false ;
for ( auto it = vCrv.begin() ; it != vCrv.end() ; ++it)
delete (*it) ;
return true ;
}
//----------------------------------------------------------------------------
void
bool
Tree::VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const
{
// verifico che il verso dei loop sia corretto controllando le relazioni tra loop
vpCrv.sort( []( ICurve* a, ICurve* b) { double AreaA, AreaB ; a->GetAreaXY( AreaA) ; b->GetAreaXY( AreaB) ; return abs(AreaA) > abs(AreaB) ;}) ;
auto it = vpCrv.begin() ;
for ( ++it ; it != vpCrv.end() ; ++it) {
bool bIdentified = false ;
for ( auto k = it ; k != vpCrv.begin() ;) {
--k ;
IntersCurveCurve icc( **k, **it) ;
int nRes = icc.GetRegionCurveClassification() ;
if ( nRes == CCREGC_IN1) {
bIdentified = true ;
vbOrientation.push_back( ! vbOrientation[ distance( vpCrv.begin(), k)]) ; // l'orientazione deve essere opposta alla prima curva che contiene la corrente
break ;
}
}
if ( ! bIdentified)
vbOrientation.push_back( vbOrientation[0]) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Tree::AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const
{
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
pCC->FromPolyLine( pl) ;
ICURVEPLIST vCrv ;
AdjustLoops( Release( pCC), vCrv, false) ;
if ( vCrv.size() > 1)
VerifyLoopOrientation( vCrv, vbOrientation) ;
for ( auto itCrv = vCrv.begin() ; itCrv != vCrv.end() ; ++itCrv) {
PolyLine plApprox ; (*itCrv)->ApproxWithLines( 0.01, 15, 0, plApprox) ;
vPl.push_back( plApprox) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax)
{
if ( pSrfBz == nullptr || ! pSrfBz->IsValid())
return false ;
// pulisco i vettori membri
m_mTree.clear() ;
m_vnLeaves.clear() ;
m_vnParents.clear() ;
m_mVert.clear() ;
m_vLoop.clear() ;
//m_vLoop.clear() ;
m_mChunk.clear() ;
m_vPlApprox.clear() ;
m_vPolygons.clear() ;
@@ -122,6 +238,15 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
m_bBilinear = true ;
if ( nSpanU * nSpanV != 1)
m_bMulti = true ;
// creo la cella Root
Point3d ptTop( nSpanU * SBZ_TREG_COEFF, nSpanV * SBZ_TREG_COEFF) ;
bool bLimited = false ;
if ( ! AreSamePointExact( ptMax,ORIG) && ! AreSamePointExact( ptMax,ptTop)) {
ptTop = ptMax ;
bLimited = true ;
}
Cell cRoot( ptMin, ptTop) ;
m_mTree.insert( pair< int, Cell>( -1, cRoot)) ;
// recupero i loop di trim e li divido per chunk
if ( m_bTrimmed) {
int nLoop = 0 ;
@@ -132,7 +257,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
for ( int i = 0 ; i < pTrimReg->GetChunkCount() ; ++ i) {
PtrOwner<SurfFlatRegion> pChunk( pTrimReg->CloneChunk( i)) ;
for ( int j = 0 ; j < pChunk->GetLoopCount( 0) ; ++ j) {
//vChunk.push_back( nLoop) ;
// i chunk della falt region sono ancora flat region composte da 1 chunk
PtrOwner<ICurve> pLoop ( pChunk->GetLoop( 0, j)) ;
// rimuovo i difetti dei loop prima di salvarli
@@ -141,9 +265,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
pCrvCompo->RemoveSmallDefects( dLinTol, dAngTolDeg, true) ;
pCrvCompo->RemoveSmallParts( dLinTol, dAngTolDeg) ;
PtrOwner<ICurve> pCrv( pCrvCompo->Clone()) ;
m_vLoop.emplace_back( Release( pLoop)) ;
m_mChunk[nLoop] = i ;
++ nLoop ;
// approssimo i loop di trim con delle spezzate
PolyLine plApprox ;
int nType = 0 ;
@@ -157,24 +279,23 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
bCCW = true ;
else
bCCW = false ;
// limito il loop allo spazio parametrico // potrei ottenere più loop a partire da quello originale
POLYLINEVECTOR vPlLimited ;
LimitLoop( plApprox, vPlLimited) ;
for ( int k = 0 ; k < int( vPlLimited.size()) ; ++k)
m_vPlApprox.push_back( tuple<PolyLine,bool>(vPlLimited[k], bCCW)) ;
POLYLINEVECTOR vPlAdjusted ;
BOOLVECTOR vbOrientation ;
vbOrientation.push_back( bCCW) ;
AdjustLoop( plApprox, vPlAdjusted, vbOrientation) ;
nLoop = int ( m_vPlApprox.size()) ;
for ( int k = 0 ; k < int( vPlAdjusted.size()) ; ++k )
m_vPlApprox.push_back( tuple<PolyLine,bool>(vPlAdjusted[k], vbOrientation[k])) ;
// aggiorno la mappa del chunk di appartenenza per tutti i loop aggiunti // do per scontato che siano tutti dello stesso chunk anche se li ho separati
//m_vLoop.emplace_back( Release( pLoop)) ;
for ( int k = nLoop ; k < int( m_vPlApprox.size()); ++k)
m_mChunk[k] = i ;
}
}
}
// salvo i vertici 3d della cella root
Point3d ptTop( nSpanU * SBZ_TREG_COEFF, nSpanV * SBZ_TREG_COEFF) ;
bool bLimited = false ;
if ( ! AreSamePointExact( ptMax,ORIG) && ! AreSamePointExact( ptMax,ptTop)) {
ptTop = ptMax ;
bLimited = true ;
}
m_mTree.clear() ;
Cell cRoot( ptMin, ptTop) ;
m_mTree.insert( pair< int, Cell>( -1, cRoot)) ;
Point3d ptP00, ptP10, ptP11, ptP01 ;
bool bOk = false ;
if ( ! bLimited) {
@@ -350,6 +471,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
m_vDim.push_back( ( dLen1 > EPS_ZERO ? dLen1 : 1)) ;
m_vDim.push_back( ( dLen2 > EPS_ZERO ? dLen2 : 1)) ;
m_vDim.push_back( ( dLen3 > EPS_ZERO ? dLen3 : 1)) ;
return true ;
}
//----------------------------------------------------------------------------
@@ -1040,7 +1162,7 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
for ( int k : vTopNeighs)
vCells.push_back( m_mTree.at( k)) ;
// le celle restituite sono ordinate per x crescente
sort( vCells.begin(), vCells.end(), Cell::minorX) ;
std::sort( vCells.begin(), vCells.end(), Cell::minorX) ;
vTopNeighs.clear() ;
for ( Cell c : vCells)
vTopNeighs.push_back( c.m_nId) ;
@@ -1122,7 +1244,7 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
for ( int k : vBottomNeighs)
vCells.push_back( m_mTree.at( k)) ;
// le celle restituite sono ordinate per x crescente
sort( vCells.begin(), vCells.end(), Cell::minorX) ;
std::sort( vCells.begin(), vCells.end(), Cell::minorX) ;
vBottomNeighs.clear() ;
for ( Cell c : vCells)
vBottomNeighs.push_back( c.m_nId) ;
@@ -1203,7 +1325,7 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
for ( int k : vLeftNeighs)
vCells.push_back( m_mTree.at( k)) ;
// le celle restituite sono ordinate per y crescente
sort( vCells.begin(), vCells.end(), Cell::minorY) ;
std::sort( vCells.begin(), vCells.end(), Cell::minorY) ;
vLeftNeighs.clear() ;
for ( Cell c : vCells)
vLeftNeighs.push_back( c.m_nId) ;
@@ -1284,7 +1406,7 @@ Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const
for ( int k : vRightNeighs)
vCells.push_back( m_mTree.at( k)) ;
// le celle restituite sono ordinate per y crescente
sort( vCells.begin(), vCells.end(), Cell::minorY) ;
std::sort( vCells.begin(), vCells.end(), Cell::minorY) ;
vRightNeighs.clear() ;
for ( Cell c : vCells)
vRightNeighs.push_back( c.m_nId) ;
@@ -1388,15 +1510,15 @@ Tree::GetDepth( int nId, int nRef = -2) const
return i ;
}
//----------------------------------------------------------------------------
struct generator
{
int value ;
generator( void)
{ value = -1 ; }
int operator() ()
{ return ++value ; }
} ;
////----------------------------------------------------------------------------
//struct generator
//{
// int value ;
// generator( void)
// { value = -1 ; }
// int operator() ()
// { return ++value ; }
//} ;
//----------------------------------------------------------------------------
bool
@@ -1419,6 +1541,7 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons)
POLYLINEVECTOR vPolygonsBasic ;
GetPolygonsBasic( vPolygonsBasic) ;
// aggiungo 4 elementi al vettore che contiene ciò che resta degli edge dopo il trim
m_vCEdge2D.clear() ;
for ( int i = 0 ; i < 4 ; ++i) {
m_vCEdge2D.emplace_back() ;
m_vCEdge2D.back().second.Init( false, EPS_SMALL, 1) ;
@@ -1444,7 +1567,8 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons)
INTVECTOR vnParentChunk ;
// vettore in cui salvo i loop che non appartengono al poligono che sto cotruendo nel ciclo attuale e da cui ripasserò dopo
INTVECTOR vToCheck( (int) m_mTree[nId].m_vInters.size()) ;
generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ;
//generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ;
iota (vToCheck.begin(), vToCheck.end(), 0) ;
// numero di poligoni aggiunti
int nPoly = 0 ;
// scorro sui vettori intersezione della cella nId e sui suoi vertici
@@ -1550,7 +1674,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells)
vNeigh.clear() ;
vVertices.push_back( m_mTree.at( nId).GetTopRight()) ;
GetTopNeigh ( nId, vNeigh) ;
reverse( vNeigh.begin(), vNeigh.end()) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top
if ( ! vNeigh.empty() && vNeigh.size() != 1) {
// se la superficie è chiusa lungo il parametro V e la cella è sul lato top
@@ -1571,7 +1695,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells)
bTopLeft = false ;
vNeigh.clear() ;
GetLeftNeigh ( nId, vNeigh) ;
reverse( vNeigh.begin(), vNeigh.end()) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left
if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) {
// se la superficie è chiusa lungo il parametro U e la cella è sul lato left
@@ -2024,7 +2148,7 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
// riordino i vettori di intersezione per ogni cella e setto il flag RightEdgeIn
for ( int nId : m_vnLeaves) {
sort( m_mTree[nId].m_vInters.begin(), m_mTree[nId].m_vInters.end()) ;
std::sort( m_mTree[nId].m_vInters.begin(), m_mTree[nId].m_vInters.end()) ;
SetRightEdgeIn( nId) ;
}
@@ -2309,7 +2433,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
INTVECTOR vNeigh, vNeigh1 ;
if ( nEdge == 0) {
GetTopNeigh( nId, vNeigh) ;
reverse( vNeigh.begin(), vNeigh.end()) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
for ( int j : vNeigh) {
if ( ptInters.x >= m_mTree[j].GetBottomLeft().x) {
nId = j ;
@@ -2329,7 +2453,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
}
else if ( nEdge == 1) {
GetLeftNeigh( nId, vNeigh) ;
reverse( vNeigh.begin(), vNeigh.end()) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
for ( int j : vNeigh) {
if ( ptInters.y >= m_mTree[j].GetBottomLeft().y) {
nId = j ;
@@ -3531,10 +3655,16 @@ Tree::CheckIfBetween( const Inters& inA, const Inters& inB) const
}
else if ( nEdge == 7)
nEdge = 0 ;
if ( AreSameEdge( inA.nIn, inA.nOut) && ! CheckIfBefore( inA.nIn, inA.vpt[0], inA.vpt.back()))
if ( AreSameEdge( inA.nIn, inA.nOut) && ! CheckIfBefore( inA.nIn, inA.vpt[0], inA.vpt.back(), nEdge))
vEdges.push_back( nEdge) ;
int nEdgeIn = inA.nIn ;
if ( nEdgeIn > 3 && nEdgeIn != 7) {
nEdgeIn = nEdgeIn - 4 ;
}
else if ( nEdgeIn == 7)
nEdgeIn = 0 ;
// creo la sequenza di Edges da scorrere per trovare i possibili validNextStart
while ( ! AreSameEdge( nEdge, inA.nIn) || (int) vEdges.size() == 0) {
while ( ! AreSameEdge( nEdge, nEdgeIn) || (int) vEdges.size() == 0) {
vEdges.push_back( nEdge) ;
if ( nEdge == 3)
nEdge = 0 ;
@@ -3625,6 +3755,8 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const
nEdge = 2 ;
else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptTR.x) < EPS_SMALL)
nEdge = 3 ;
else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x)
nEdge = -1 ;
else
return false ;
return true ;
@@ -3642,10 +3774,10 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
GetRootNeigh( 0, vEdges[0]) ;
// le celle sui bordi orizzontali sono ordinate per x o y crescente, ma i io voglio costruire gli edge in senso antiorario a partire dal ptTR,
// quindi devo invertire gli Edge 0 e 1
reverse( vEdges[0].begin(), vEdges[0].end()) ;
std::reverse( vEdges[0].begin(), vEdges[0].end()) ;
vEdges.emplace_back() ;
GetRootNeigh( 1, vEdges[1]) ;
reverse( vEdges[1].begin(), vEdges[1].end()) ;
std::reverse( vEdges[1].begin(), vEdges[1].end()) ;
vEdges.emplace_back() ;
GetRootNeigh( 2, vEdges[2]) ;
vEdges.emplace_back() ;
@@ -3855,12 +3987,12 @@ Tree::AdjustCuts( void)
if ( int( m_mTree.at( -1).m_vInters.size()) == 1)
return true ;
// li riordino per ordine di quali taglio incontrerei percorrendo il bordo della cella a partire da ptTR
sort( m_mTree.at( -1).m_vInters.begin(), m_mTree.at( -1).m_vInters.end(), [](Inters& a, Inters& b){ return Inters::FirstEncounter(a,b) ;}) ;
std::sort( m_mTree.at( -1).m_vInters.begin(), m_mTree.at( -1).m_vInters.end(), [](Inters& a, Inters& b){ return Inters::FirstEncounter(a,b) ;}) ;
// ora controllo che le intersezioni che trovo siano ingressi alternati ad uscite, sennò inverto l'intersezione
bool bPreviousWasStart = m_mTree.at( -1).m_vInters.at(0).bSortedbyStart ;
for ( int i = 0 ; i < int( m_mTree.at( -1).m_vInters.size()); ++i) {
if ( m_mTree.at( -1).m_vInters.at(i).bSortedbyStart == bPreviousWasStart) {
reverse( m_mTree.at( -1).m_vInters.at(i).vpt.begin(), m_mTree.at( -1).m_vInters.at(i).vpt.end()) ;
std::reverse( m_mTree.at( -1).m_vInters.at(i).vpt.begin(), m_mTree.at( -1).m_vInters.at(i).vpt.end()) ;
int nEdgeOutNew = m_mTree.at( -1).m_vInters.at(i).nIn ;
m_mTree.at( -1).m_vInters.at(i).nIn = m_mTree.at( -1).m_vInters.at(i).nOut ;
m_mTree.at( -1).m_vInters.at(i).nOut = nEdgeOutNew ;
@@ -3883,7 +4015,8 @@ Tree::CreateCellContour( POLYLINEMATRIX& vPolygons)
// preparo tutto per poter chiamare la createCellPolygon
m_vnLeaves.push_back( nRoot) ;
INTVECTOR vToCheck( (int) m_mTree.at(nRoot).m_vInters.size()) ;
generate_n( vToCheck.begin(), (int) m_mTree.at(nRoot).m_vInters.size(), generator()) ;
//generate_n( vToCheck.begin(), (int) m_mTree.at(nRoot).m_vInters.size(), generator()) ;
iota( vToCheck.begin(), vToCheck.end(), 0) ;
int nPoly = 0 ;
INTVECTOR vnParentChunk ;
PolyLine pl ;
@@ -3899,5 +4032,217 @@ Tree::CreateCellContour( POLYLINEMATRIX& vPolygons)
if ( nPolyBefore == nPoly)
break ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Tree::CloseOpenCuts( POLYLINEVECTOR& vPL, PolyLine& plNew) const // da verificare e comunque funzione probabilmente inutile
{
if ( vPL.size() == 1 && vPL[0].IsClosed()) {
plNew = vPL[0] ;
return true ;
}
vector<Inters> vInters ;
for ( int i = 0 ; i < int( vPL.size()) ; ++i) {
vInters.emplace_back() ;
Point3d ptStart ; vPL[i].GetFirstPoint( ptStart) ;
OnWhichEdge( -1, ptStart, vInters.back().nIn) ;
Point3d ptEnd ; vPL[i].GetLastPoint( ptEnd) ;
OnWhichEdge( -1, ptEnd, vInters.back().nOut) ;
PNTULIST lPnt = vPL[i].GetUPointList() ;
for ( auto it = lPnt.begin() ; it != lPnt.end() ; ++it)
vInters.back().vpt.push_back( (*it).first) ;
}
std::sort( vInters.begin(), vInters.end(), [](Inters &left, Inters &right) { return left < right;}) ;
bool bNotCameBack = true ;
int nEdge = vInters[0].nOut ;
PNTULIST lPnt = vPL[0].GetUPointList() ;
for ( auto it = lPnt.begin() ; it != lPnt.end() ; ++it)
plNew.AddUPoint( (*it).second, (*it).first) ;
// se ero in un vertice passo all'edge successivo
if ( nEdge > 3 && nEdge != 7)
nEdge = nEdge - 4 ;
else if ( nEdge == 7)
nEdge = 0 ;
int nInters = 0 ;
while ( bNotCameBack) {
bool bAtNextStart = false ;
//PolyLine plEdge ;
double dCount ; plNew.GetLastU( dCount) ;
plNew.AddUPoint( dCount, vInters[nInters].vpt.back()) ;
++ dCount ;
++ nInters ;
if ( nInters == vInters.size())
nInters = 0 ;
// scorro tutti i lati finché non torno allo start del loop
while( ! bAtNextStart) {
Point3d ptToAdd ;
if ( nEdge == 0)
ptToAdd = m_mTree.at(-1).GetTopLeft() ;
else if ( nEdge == 1)
ptToAdd = m_mTree.at(-1).GetBottomLeft() ;
else if ( nEdge == 2)
ptToAdd = m_mTree.at(-1).GetBottomRight() ;
else if ( nEdge == 3)
ptToAdd = m_mTree.at(-1).GetTopRight() ;
if ( plNew.AddUPoint( dCount, ptToAdd))
++ dCount ;
if ( nEdge > 3 && nEdge != 7)
nEdge = nEdge - 4 ;
else if ( nEdge < 3)
++ nEdge ;
else
nEdge = 0 ;
if ( AreSameEdge(nEdge,vInters[nInters].nIn))
bAtNextStart = true ;
}
if ( nInters != 0 && nInters < int(vPL.size())) {
// aggiungo la polyline successiva
PNTULIST lPnt = vPL[nInters].GetUPointList() ;
double dLastU ; vPL[nInters-1].GetLastU( dLastU) ;
++ dLastU ;
for ( auto it = lPnt.begin() ; it != lPnt.end() ; ++it)
plNew.AddUPoint( dLastU + (*it).second, (*it).first) ;
}
if ( AreSameEdge(nEdge, vInters[0].nIn)) {
plNew.Close() ;
bNotCameBack = false ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Tree::CloseOpenCuts( void)
{
int nRoot = -1 ;
// tra i loop del parametrico seleziono quelli aperti
// creo il vettore inters, lo riordino e poi rendo chiusi i loop ( che possono restare indipendenti o unirsi ad altri loop aperti)
INTVECTOR vOpen ;
for ( int i = 0 ; i < int(m_vPlApprox.size()) ; ++i ) {
if ( ! get<0>(m_vPlApprox[i]).IsClosed()) {
m_mTree.at( nRoot).m_vInters.emplace_back() ;
Point3d ptStart ; get<0>(m_vPlApprox[i]).GetFirstPoint( ptStart) ;
OnWhichEdge( nRoot, ptStart, m_mTree.at( nRoot).m_vInters.back().nIn) ;
Point3d ptEnd ; get<0>(m_vPlApprox[i]).GetLastPoint( ptEnd) ;
OnWhichEdge( nRoot, ptEnd, m_mTree.at( nRoot).m_vInters.back().nOut) ;
vOpen.push_back( i) ;
}
}
// riordino le intersezioni
std::sort( m_mTree.at(nRoot).m_vInters.begin(), m_mTree.at(nRoot).m_vInters.end()) ;
m_vnLeaves.push_back( -1) ;
// chiamo la GetPolygons
POLYLINEMATRIX mPL ;
GetPolygons( mPL) ;
//creo il nuovo vettore di polyline di trim
// tengo quelli che erano i trim chiusi
for ( int t = int(vOpen.size()) - 1 ; t > -1 ; ++t ) {
m_vPlApprox.erase( m_vPlApprox.begin() + vOpen[t]) ;
}
// aggiungo i nuovi trim creati
for ( int t = 0 ; t < int( mPL[0].size()) ; ++t) {
m_vPlApprox.push_back( pair<PolyLine, bool>(mPL[0][t], true)) ;
}
m_vnLeaves.clear() ;
m_mTree.at( nRoot).m_vInters.clear() ;
//// tra i loop del parametrico seleziono quelli aperti
//// creo il vettore inters, lo riordino e poi rendo chiusi i loop ( che possono restare indipendenti o unirsi ad altri loop aperti)
//vector<pair<int,Inters>> vInters ;
//INTVECTOR vClosed ;
//for ( int i = 0 ; i < int(m_vPlApprox.size()) ; ++i ) {
// if ( ! get<0>(m_vPlApprox[i]).IsClosed()) {
// vInters.emplace_back() ;
// vInters.back().first = i ;
// Point3d ptStart ; get<0>(m_vPlApprox[i]).GetFirstPoint( ptStart) ;
// OnWhichEdge( -1, ptStart, vInters.back().second.nIn) ;
// Point3d ptEnd ; get<0>(m_vPlApprox[i]).GetLastPoint( ptEnd) ;
// OnWhichEdge( -1, ptEnd, vInters.back().second.nOut) ;
// }
// else
// vClosed.push_back( i) ;
//}
//// A MANO
//// chiudo le curve aperte e se necessario le giunto tra loro
//if ( vInters.size() != 0) {
// ICurveComposite* pCCOpen ( CreateBasicCurveComposite()) ;
// pCCOpen->FromPolyLine( get<0>(m_vPlApprox[vInters[0].first])) ;
// //sort( vInters.begin(), vInters.end()) ;
// sort( vInters.begin(), vInters.end(), [](pair<int,Inters> &left, pair<int,Inters> &right) { return left.second < right.second;}) ;
// bool bNotCameBack = true ;
// int nEdge = vInters[0].second.nOut ;
// // se ero in un vertice passo all'edge successivo
// if ( nEdge > 3 && nEdge != 7)
// nEdge = nEdge - 4 ;
// else if ( nEdge == 7)
// nEdge = 0 ;
// int nInters = 0 ;
// while ( bNotCameBack) {
// bool bAtNextStart = false ;
// PolyLine plEdge ;
// int nCount = 0 ;
// plEdge.AddUPoint( nCount, vInters[nInters].ptEnd) ;
// ++ nCount ;
// ++ nInters ;
// if ( nInters == vInters.size())
// nInters = 0 ;
// // scorro tutti i lati finché non torno allo start del loop
// while( ! bAtNextStart) {
// Point3d ptToAdd ;
// if ( nEdge == 0)
// ptToAdd = m_mTree.at(-1).GetTopLeft() ;
// else if ( nEdge == 1)
// ptToAdd = m_mTree.at(-1).GetBottomLeft() ;
// else if ( nEdge == 2)
// ptToAdd = m_mTree.at(-1).GetBottomRight() ;
// else if ( nEdge == 3)
// ptToAdd = m_mTree.at(-1).GetTopRight() ;
// if ( plEdge.AddUPoint( nCount, ptToAdd))
// ++ nCount ;
// if ( nEdge > 3 && nEdge != 7)
// nEdge = nEdge - 4 ;
// else if ( nEdge < 3)
// ++ nEdge ;
// else
// nEdge = 0 ;
// if ( AreSameEdge(nEdge,vInters[nInters].second.nIn))
// bAtNextStart = true ;
// }
// ICurveComposite* pCC( CreateCurveComposite()) ;
// pCC->FromPolyLine( plEdge) ;
// // aggiungo il tratto di edge
// pCCOpen->AddCurve( pCC) ;
// // agggiungo il prossio taglio
// if ( nInters != 0)
// pCCOpen->AddCurve( Release( vInters[nInters].pCrv)) ;
// if ( AreSameEdge(nEdge, vInters[0].second.nIn)) {
// pCCOpen->Close() ;
// bNotCameBack = false ;
// }
// }
// if ( ! pCCOpen->IsClosed()) {
// LOG_ERROR( pGenLog, "Error creating the contour from open trims") ;
// return nullptr ;
// }
// if ( ! bPlanarSurf) {
// if ( ! SimplifyCurve( pCCOpen)) {
// LOG_ERROR( pGenLog, "Error simplifying the contour recreated from the open trims") ;
// return nullptr ;
// }
// }
// SfrCntr.AddCurve( pCCOpen) ;
//}
return true ;
}
+8 -4
View File
@@ -231,9 +231,9 @@ class Tree
public :
~Tree( void) ;
Tree( void) ;
Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
//Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
Tree( const Point3d ptBl, const Point3d ptTr) ; // creatore da usare solo nel caso in cui si voglia aggiungere tagli ad un'unica cella e del risultato ottenere il contorno
void SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
bool SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini)
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax il massimo per la dimensione maggiore di un triangolo della trimesh
// dSideMin lunghezza minima del lato di una cella nello spazio reale
@@ -254,7 +254,7 @@ class Tree
std::vector<bool> GetPoles( void) { return m_vbPole ;} ; // funzione che restituisce i flag che indicano se i lati sono collassati in dei poli
private :
bool LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl) const ; // funzione che limita i loop di trim allo spazio parametrico
bool LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ; // funzione che limita i loop di trim allo spazio parametrico
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
bool Split( int nId) ; // funzione di split di una cella dell'albero a met nella direzione data da bVert
void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profondit di +- 1
@@ -285,6 +285,10 @@ class Tree
bool OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const ; // indica a quale edge o vertice il punto è vicino entro EPS_SMALL
bool AdjustCuts( void) ;
bool UpdateSplitLoop( PolyLine& pl, int& nCount, Point3d& pt) ;
bool CloseOpenCuts( void) ;
bool CloseOpenCuts( POLYLINEVECTOR& vPL, PolyLine& pl) const ;
bool VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const ; // verifico l'orientazione ( CCW o CW) delle polyline in base a come sono contenute le une nelle altre
bool AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ;
private :
@@ -293,7 +297,7 @@ class Tree
bool m_bTrimmed ; // superficie trimmata
//INTMATRIX m_vChunk ; // elenco dei loop divisi per chunk
std::map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
ICURVEPOVECTOR m_vLoop ; // curve di loop
//ICURVEPOVECTOR m_vLoop ; // curve di loop
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW
bool m_bBilinear ; // superficie bilineare
bool m_bMulti ; // superficie multi-patch
+19
View File
@@ -2172,6 +2172,25 @@ VolZmap::SetChiselTool( const string& sToolName, double dH, double dW, double dT
return m_vTool[m_nCurrTool].SetChiselTool( sToolName, dH, dW, dTh, nFlag) ;
}
//----------------------------------------------------------------------------
bool
VolZmap::SetAdditiveTool( const std::string& sToolName,
double dH, double dR, double dRC, int nFlag, bool bFirst)
{
if ( bFirst) {
m_vTool.resize( 1) ;
m_vTool[0].Clear( true) ;
}
else
m_vTool.emplace_back( true) ;
m_nCurrTool = int( m_vTool.size()) - 1 ;
if ( m_nCurrTool < 0)
return false ;
m_vTool[m_nCurrTool].SetTolerances( m_dToolLinTol, m_dToolAngTolDeg) ;
return m_vTool[m_nCurrTool].SetAdditiveTool( sToolName, dH, dR, dRC, nFlag) ;
}
//----------------------------------------------------------------------------
int
VolZmap::GetToolCount( void) const
+11
View File
@@ -78,6 +78,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
bool Clear( void) override ;
bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ;
bool CreateEmptyMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) override ;
bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) override ;
bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex) override ;
int GetBlockCount( void) const override ;
@@ -109,6 +110,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
double dH, double dW, double dTh, double dRc, int nFlag, bool bFirst) override ;
bool SetChiselTool( const std::string& sToolName,
double dH, double dW, double dTh, int nFlag, bool bFirst) override ;
bool SetAdditiveTool( const std::string& sToolName,
double dH, double dR, double dRC, int nFlag, bool bFirst) override ;
int GetToolCount( void) const override ;
bool SetCurrTool( int nCurrTool) override ;
bool ResetTools( void) override ;
@@ -319,6 +322,14 @@ class VolZmap : public IVolZmap, public IGeoObjRW
const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realtà MillingPerp
// Generica traslazione sfera
bool CompBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad, int nToolNum) ;
// Additivi
bool AddingMotion( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) ;
bool AddingCylinder( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dRad) ;
bool AddingTruncatedCone( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx,
double dMaxRad, double dMinRad, double dHei,
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ;
bool AddingSphere( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad) ;
bool AddingGeneral( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) ;
// BBox per utensili e solidi semplici con movimenti di traslazione
inline bool TestToolBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV,
int& nStI, int& nStJ, int& nEnI, int& nEnJ) ;
+85 -11
View File
@@ -1,4 +1,4 @@
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// EgalTech 2015-2016
//----------------------------------------------------------------------------
// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
@@ -29,11 +29,11 @@ using namespace std ;
bool
VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex)
{
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL)
return false ;
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
m_dStep = max( dStep, 100 * EPS_SMALL) ;
// Aggiorno la dimensione della mappa 1 o 3
@@ -133,6 +133,80 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateEmptyMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex)
{
// Controlli sull'ammissibilit delle dimensioni lineari del grezzo e del passo
if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL)
return false ;
// Il passo di discretizzazione non pu essere inferiore a 100 * EPS_SMALL
m_dStep = max( dStep, 100 * EPS_SMALL) ;
// Aggiorno la dimensione della mappa 1 o 3
m_nMapNum = ( bTriDex ? 3 : 1) ;
// Disponendo i sistemi di riferimento in una successione, le coordinate x,y,z
// di uno si ottengono da una permutazione ciclica di quelle del precedente sistema.
// es: X(n) = Z(n-1), Y(n) = X(n-1), Z(n) = Y(n-1)
// Definisco il sistema di riferimento intrinseco
m_MapFrame.Set( ptO, X_AX, Y_AX, Z_AX) ;
// Definisco i vettori dei limiti su indici
m_nNx[0] = max( int( ( dLengthX + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNy[0] = max( int( ( dLengthY + EPS_SMALL) / m_dStep + 0.5), 1) ;
// Numero di componenti connesse
m_nConnectedCompoCount = 1 ;
// Se tridexel
if ( bTriDex) {
m_nNx[1] = m_nNy[0] ;
m_nNy[1] = max( int( ( dLengthZ + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNx[2] = m_nNy[1] ;
m_nNy[2] = m_nNx[0] ;
}
// altrimenti mono dexel
else {
m_nNx[1] = 0 ;
m_nNy[1] = 0 ;
m_nNx[2] = 0 ;
m_nNy[2] = 0 ;
}
// Definisco il numero di blocchi lungo x,y e z
if ( ! CalcBlockNum())
return false ;
// Creazione delle mappe
// Calcolo del numero di celle per ogni mappa
for ( int i = 0 ; i < m_nMapNum ; ++ i)
m_nDim[i] = m_nNx[i] * m_nNy[i] ;
// Creazione delle celle per ogni mappa
for ( int i = 0 ; i < m_nMapNum ; ++ i)
m_Values[i].resize( m_nDim[i]) ;
// Definizione delle limitazioni iniziali in Z per ogni mappa
m_dMinZ[0] = 0 ;
m_dMaxZ[0] = dLengthZ ;
m_dMinZ[1] = 0 ;
m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ;
m_dMinZ[2] = 0 ;
m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ;
// Tipologia
m_nShape = GENERIC ;
// Aggiornamento dello stato
m_nStatus = OK ;
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex)
@@ -140,7 +214,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
// Aggiorno la dimensione della mappa 1 o 3
m_nMapNum = ( bTriDex ? 3 : 1) ;
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
m_dStep = max( dStep, 100 * EPS_SMALL) ;
// Determino il bounding box della flat region
@@ -223,11 +297,11 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
CRVCVECTOR IntersectionResults ;
Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ;
// Analizzo le parti in cui la retta è stata divisa
// Analizzo le parti in cui la retta è stata divisa
int nPart = int( IntersectionResults.size()) ;
for ( int k = 0 ; k < nPart ; ++ k) {
// Se la retta è interna alla regione o coincidente con parte della sua frontiera
// Se la retta è interna alla regione o coincidente con parte della sua frontiera
int nType = IntersectionResults[k].nClass ;
if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) {
@@ -334,7 +408,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
int nPart = int( IntersectionResults.size()) ;
for ( int k = 0 ; k < nPart ; ++ k) {
// Se la retta è interna alla regione o coincidente con parte della sua frontiera
// Se la retta è interna alla regione o coincidente con parte della sua frontiera
int nType = IntersectionResults[k].nClass ;
if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) {
@@ -471,7 +545,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
int nIntType = IntersectionResults[k].nILTT ;
// Se c'è intersezione
// Se c'è intersezione
if ( nIntType != ILTT_NO) {
double dCos = IntersectionResults[k].dCosDN ;
@@ -527,7 +601,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
bool
VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex)
{
// Se la superficie non è chiusa oppure orientata al contrario non ha senso continuare
// Se la superficie non è chiusa oppure orientata al contrario non ha senso continuare
double dVol ;
if ( ! Surf.IsClosed() || ! Surf.GetVolume( dVol) || dVol < 0)
return false ;
@@ -543,14 +617,14 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
Point3d ptMapOrig, ptMapEnd ;
SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ;
// Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione,
// Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione,
// quindi espandiamo il bounding box per ovviare al problema.
SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 100 * EPS_SMALL) ;
// Sistema di riferimento intrinseco dello Zmap
m_MapFrame.Set( ptMapOrig, Frame3d::TOP) ;
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
m_dStep = max( dStep, 100 * EPS_SMALL) ;
// Determino le dimensioni lineari del BBox
+970 -273
View File
File diff suppressed because it is too large Load Diff