Merge commit 'e490c173e84ed5bf576888ac4bc5f023c49680f7' into VmillAdditivo
This commit is contained in:
@@ -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 ;
|
||||
|
||||
+33
-4
@@ -535,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]) ;
|
||||
@@ -545,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) ;
|
||||
@@ -553,8 +584,6 @@ 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 ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,7 +597,7 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
|
||||
}
|
||||
}
|
||||
if ( bCollapsed)
|
||||
return true ;
|
||||
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
|
||||
|
||||
+12
-8
@@ -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 ;
|
||||
}
|
||||
@@ -618,6 +620,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
||||
if ( pRescaledSfr->IsValid()) {
|
||||
if ( bRetry)
|
||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; //contro OFFSET
|
||||
delete pSfr ;
|
||||
pSfr = Release( pRescaledSfr) ;
|
||||
}
|
||||
}
|
||||
@@ -629,6 +632,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
||||
if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) {
|
||||
if ( bRetry)
|
||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // contro OFFSET
|
||||
delete pSfr ;
|
||||
pSfr = Release( pRescaledSfr) ;
|
||||
}
|
||||
|
||||
|
||||
+7
-5
@@ -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() ;
|
||||
@@ -3112,7 +3114,7 @@ SurfBezier::GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge) con
|
||||
ICurveComposite*
|
||||
SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
|
||||
{
|
||||
if ( m_mCCEdge.size() == 0)
|
||||
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)
|
||||
@@ -3213,10 +3215,10 @@ bool
|
||||
SurfBezier::IsPlanar( void) const
|
||||
{
|
||||
// costruisco il contorno della superficie unendo gli edge e chiedo se la polyline è piana.
|
||||
PtrOwner<ICurveComposite> pCCEdge( GetSingleEdge3D( true, 0)) ;
|
||||
pCCEdge->AddCurve( GetSingleEdge3D( true, 1)) ;
|
||||
pCCEdge->AddCurve( GetSingleEdge3D( true, 2)) ;
|
||||
pCCEdge->AddCurve( GetSingleEdge3D( true, 3)) ;
|
||||
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 ;
|
||||
|
||||
+20
-7
@@ -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() ;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#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"
|
||||
@@ -64,36 +65,144 @@ 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()) {
|
||||
pParamTrim->Offset( 10 * EPS_SMALL, ICurve::OFF_EXTEND) ;
|
||||
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) {
|
||||
// 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) ;
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
for ( auto it = vCrv.begin() ; it != vCrv.end() ; ++it)
|
||||
delete (*it) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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 ;
|
||||
}
|
||||
|
||||
@@ -108,7 +217,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
|
||||
m_vnLeaves.clear() ;
|
||||
m_vnParents.clear() ;
|
||||
m_mVert.clear() ;
|
||||
m_vLoop.clear() ;
|
||||
//m_vLoop.clear() ;
|
||||
m_mChunk.clear() ;
|
||||
m_vPlApprox.clear() ;
|
||||
m_vPolygons.clear() ;
|
||||
@@ -129,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 ;
|
||||
@@ -139,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
|
||||
@@ -148,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 ;
|
||||
@@ -164,25 +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 ;
|
||||
if ( ! LimitLoop( plApprox, vPlLimited))
|
||||
return false ;
|
||||
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) {
|
||||
@@ -1049,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) ;
|
||||
@@ -1131,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) ;
|
||||
@@ -1212,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) ;
|
||||
@@ -1293,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) ;
|
||||
@@ -1428,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) ;
|
||||
@@ -1560,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
|
||||
@@ -1581,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
|
||||
@@ -2034,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) ;
|
||||
}
|
||||
|
||||
@@ -2319,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 ;
|
||||
@@ -2339,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 ;
|
||||
@@ -3641,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 ;
|
||||
@@ -3658,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() ;
|
||||
@@ -3871,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 ;
|
||||
@@ -3916,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 ;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user