EgtGeomKernel 2.3j :

- modifiche a SurfTriMesh::Cut (più semplice abilitare calcolo con facce invece di triangoli)
- ora CurveClassification (di Regioni e Curve) ricevono anche il parametro dMinLen.
This commit is contained in:
DarioS
2021-10-24 17:57:53 +02:00
parent add949b6a6
commit 1d1fb41212
11 changed files with 255 additions and 201 deletions
+153 -131
View File
@@ -2573,23 +2573,14 @@ SurfTriMesh::CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bo
//----------------------------------------------------------------------------
int
SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& ExtLoop, const Plane3d& plCutPlane,
LineFacetClassVector& IntersLinePart)
SurfTriMesh::VerifyLoopPlane( const PolyLine& ExtLoop, const Plane3d& plCutPlane)
{
// Se la regione o il piano non sono validi, non è possibile proseguire.
if ( ! ( Region.IsValid() && plCutPlane.IsValid()))
// Verifico il loop e il piano di taglio
if ( ExtLoop.GetPointNbr() == 0 || ! plCutPlane.IsValid())
return FPI_ERROR ;
// Determino il piano della regione.
Plane3d plFacetPlane ;
plFacetPlane.Set( Region.GetPlanePoint(), Region.GetNormVersor()) ;
// Se il piano della regione non è valido, non è possibile proseguire.
if ( ! plCutPlane.IsValid())
return FPI_ERROR ;
// Pulisco il vettore delle intersezioni risultanti.
IntersLinePart.resize( 0) ;
// Calcolo le distanze dei vertici della faccia dal piano.
// Calcolo le distanze dei vertici della faccia dal piano
int nExtLoopPointNum = int( ExtLoop.GetPointNbr()) ;
vector<double> vDist ;
DBLVECTOR vDist ;
vDist.reserve( nExtLoopPointNum) ;
Point3d ptP ;
bool bContinue = ExtLoop.GetFirstPoint( ptP) ;
@@ -2597,7 +2588,7 @@ SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& Ext
vDist.emplace_back( DistPointPlane( ptP, plCutPlane)) ;
bContinue = ExtLoop.GetNextPoint( ptP) ;
}
// Verifico posizione della faccia rispetto al piano.
// Verifico posizione della faccia rispetto al piano.
int nVertPos = 0 ; int nVertNeg = 0 ;
for ( const auto& dDist : vDist) {
if ( dDist > 0.5 * EPS_SMALL)
@@ -2611,36 +2602,58 @@ SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& Ext
return FPI_ON ;
// Tutto dentro
else if ( nVertPos == 0)
return FPI_INN ;
return FPI_IN ;
// Tutto fuori
else if ( nVertNeg == 0)
return FPI_OUT ;
// Si intersecano
else
return FPI_CUT ;
}
//----------------------------------------------------------------------------
int
SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const Plane3d& plCutPlane,
LineFacetClassVector& IntersLinePart)
{
// Verifico la regione e il piano di taglio
if ( ! Region.IsValid() || ! plCutPlane.IsValid())
return FPI_ERROR ;
// Recupero il piano della regione.
Plane3d plFacetPlane ;
plFacetPlane.Set( Region.GetPlanePoint(), Region.GetNormVersor()) ;
if ( ! plFacetPlane.IsValid())
return FPI_ERROR ;
// Pulisco il vettore delle intersezioni
IntersLinePart.resize( 0) ;
// Intersezione tra i piani delle due facce
Point3d ptL ; Vector3d vtL ;
int nResPP = IntersPlanePlane( plFacetPlane, plCutPlane, ptL, vtL) ;
// Non essendo complanari, se non trovo la retta d'intersezione c'è un errore.
// Sono considerate non complanari, se c'è la retta d'intersezione è errore
if ( nResPP == IPPT_NO || nResPP == IPPT_OVERLAPS)
return FPI_ERROR ;
// Box contenente entrambe le regioni
// Box della regione
BBox3d b3Box ;
Region.GetLocalBBox( b3Box) ;
b3Box.Expand( 10) ;
// Limito la retta nel box contenente le regioni
// Limito la retta nel box contenente la regione
INTDBLVECTOR vInters ;
if ( ! IntersLineBox( ptL, vtL, 100., b3Box, vInters, false) || int( vInters.size()) < 2)
return FPI_ERROR ;
double dLen = vInters.back().second - vInters[0].second ;
Point3d ptIntLineSt = ptL + vInters[0].second * vtL ;
double dLen = vInters.back().second - vInters.front().second ;
Point3d ptIntLineSt = ptL + vInters.front().second * vtL ;
Point3d ptIntLineEn = ptL + vInters.back().second * vtL ;
CurveLine cvPlaneIntersLine ;
cvPlaneIntersLine.Set( ptIntLineSt, ptIntLineEn) ;
// Limito la linea di intersezione con la faccia.
// Classifico la linea di intersezione con la faccia
CRVCVECTOR IntersectionResults ;
bool bClassificationOk = Region.GetCurveClassification( cvPlaneIntersLine, IntersectionResults) ;
bool bClassificationOk = Region.GetCurveClassification( cvPlaneIntersLine, 0.1 * EPS_SMALL, IntersectionResults) ;
// Se non trovo le intersezioni, c'è un errore.
if ( ! bClassificationOk)
return FPI_ERROR ;
@@ -2655,8 +2668,17 @@ SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& Ext
IntersLinePart.emplace_back( LineFacetClass( ptIntLineSt + dParS * vtL, ptIntLineSt + dParE * vtL, nType, nType)) ;
}
}
if ( ! IntersLinePart.empty())
return FPI_CUT ;
return int( IntersLinePart.size()) > 0 ;
// La linea si è ridotta ad un punto, la regione è tutta dentro o tutta fuori
Point3d ptCen ;
if ( ! Region.GetChunkCentroid( 0, ptCen))
return FPI_ERROR ;
if ( DistPointPlane( ptCen, plCutPlane) > 0)
return FPI_OUT ;
else
return FPI_IN ;
}
//----------------------------------------------------------------------------
@@ -2744,11 +2766,11 @@ SurfTriMesh::IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& Ex
// Limito la linea di intersezione con la faccia A
CRVCVECTOR IntersectionResultsA ;
bool bClassificationOk = RegionA.GetCurveClassification( cvPlaneIntersLine, IntersectionResultsA) ;
bool bClassificationOk = RegionA.GetCurveClassification( cvPlaneIntersLine, 0.1 * EPS_SMALL, IntersectionResultsA) ;
// Limito la linea di intersezione con la faccia B
CRVCVECTOR IntersectionResultsB ;
bClassificationOk = bClassificationOk && RegionB.GetCurveClassification( cvPlaneIntersLine, IntersectionResultsB) ;
bClassificationOk = bClassificationOk && RegionB.GetCurveClassification( cvPlaneIntersLine, 0.1 * EPS_SMALL, IntersectionResultsB) ;
if ( ! bClassificationOk)
return false ;
@@ -2830,7 +2852,7 @@ ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop)
}
}
// Se il punto non sta sul loop, errore
if ( dMinSqDist > 100 * SQ_EPS_SMALL)
if ( dMinSqDist > 4 * SQ_EPS_SMALL)
return false ;
// Se il punto non sta su un vertice del segmento, lo aggiungo. Altrimenti non devo fare nulla.
auto itNewPointSt = LoopList.begin() ;
@@ -2896,7 +2918,7 @@ PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int&
}
}
// Se il punto non sta sul loop, lo segnalo.
if ( dMinSqDist > 100 * SQ_EPS_SMALL)
if ( dMinSqDist > 4 * SQ_EPS_SMALL)
return false ;
// Calcolo il parametro lungo il segmento.
Vector3d vtSeg = itMinDistEn->first - itMinDistSt->first ;
@@ -3114,7 +3136,7 @@ SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine
}
}
// Se il punto non sta sul loop, lo segnalo.
if ( dMinSqDist > 100 * SQ_EPS_SMALL)
if ( dMinSqDist > 4 * SQ_EPS_SMALL)
return false ;
// Se il punto di stop sta su un vertice non devo aggiungerlo e il
// punto di stop sarà uno degli estremi del segmento su cui giace.
@@ -3185,13 +3207,13 @@ bool
SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet)
{
for ( auto it = IntersLineMap.begin() ; it != IntersLineMap.end() ; ++ it) {
// Normale alla faccia
// Normale alla faccia
Vector3d vtFacetNorm ;
GetFacetNormal( it->first, vtFacetNorm) ;
// Creo i loop
// Creo i loop
ChainCurves LoopCreator ;
LoopCreator.Init( false, 10 * EPS_SMALL, int( it->second.size()), 10) ;
// Carico le curve per concatenarle
// Carico le curve per concatenarle
for ( int nCv = 0 ; nCv < int( it->second.size()); ++ nCv) {
Point3d ptSt = it->second[nCv].ptSt ;
Point3d ptEn = it->second[nCv].ptEn ;
@@ -3199,31 +3221,31 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
vtDir.Normalize() ;
LoopCreator.AddCurve( nCv + 1, ptSt, vtDir, ptEn, vtDir) ;
}
// Recupero i concatenamenti e li divido fra chiusi e aperti.
INTVECTOR vIds ;
Point3d ptNearStart = ( it->second.size() > 0 ? it->second[0].ptSt : ORIG) ;
// Recupero i concatenamenti e li divido fra chiusi e aperti.
INNCHAINVECTOR cvClosedChain ;
INNCHAINVECTOR cvOpenChain ;
INTVECTOR vIds ;
Point3d ptNearStart = ( it->second.size() > 0 ? it->second[0].ptSt : ORIG) ;
while ( LoopCreator.GetChainFromNear( ptNearStart, false, vIds)) {
IntersInnChain chTemp ;
for ( auto i : vIds) {
// Aggiungo la linea alla curva composta.
// Aggiungo la linea alla curva composta.
for ( auto i : vIds)
chTemp.emplace_back( it->second[i - 1]) ;
}
int nCurLoopLast = max( int( chTemp.size()) - 1, 0) ;
if ( AreSamePointEpsilon( chTemp[0].ptSt, chTemp[nCurLoopLast].ptEn, 10 * EPS_SMALL) && nCurLoopLast > 0)
// Inserisco opportunamente negli aperti o chiusi
int nCurLoopLast = int( chTemp.size()) - 1 ;
if ( nCurLoopLast > 0 && AreSamePointEpsilon( chTemp[0].ptSt, chTemp[nCurLoopLast].ptEn, 10 * EPS_SMALL))
cvClosedChain.emplace_back( chTemp) ;
else
cvOpenChain.emplace_back( chTemp) ;
}
// Elimino la seconda copia di catene aperte doppie
// Elimino la seconda copia di catene aperte doppie
for ( int nI = 0 ; nI < int( cvOpenChain.size()) - 1 ; ++ nI) {
for ( int nJ = nI + 1 ; nJ < int( cvOpenChain.size()) ; ++ nJ) {
if ( cvOpenChain[nI].size() == cvOpenChain[nJ].size()) {
bool bSame = true ;
for ( int nK = 0 ; nK < int( cvOpenChain[nI].size()) ; ++ nK) {
if ( ! AreSamePointEpsilon( cvOpenChain[nI][nK].ptSt, cvOpenChain[nJ][nK].ptSt, 10 * EPS_SMALL) ||
! AreSamePointEpsilon( cvOpenChain[nI][nK].ptEn, cvOpenChain[nJ][nK].ptEn, 10 * EPS_SMALL)) {
if ( ! AreSamePointEpsilon( cvOpenChain[nI][nK].ptSt, cvOpenChain[nJ][nK].ptSt, EPS_SMALL) ||
! AreSamePointEpsilon( cvOpenChain[nI][nK].ptEn, cvOpenChain[nJ][nK].ptEn, EPS_SMALL)) {
bSame = false ;
break ;
}
@@ -3235,14 +3257,14 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
}
}
}
// Elimino la seconda copia di catene chiuse doppie
// Elimino la seconda copia di catene chiuse doppie
for ( int nI = 0 ; nI < int( cvClosedChain.size()) - 1 ; ++ nI) {
for ( int nJ = nI + 1 ; nJ < int( cvClosedChain.size()) ; ++ nJ) {
if ( cvClosedChain[nI].size() == cvClosedChain[nJ].size()) {
bool bSame = true ;
for ( int nK = 0 ; nK < int( cvClosedChain[nI].size()) ; ++ nK) {
if ( ! AreSamePointEpsilon( cvClosedChain[nI][nK].ptSt, cvClosedChain[nJ][nK].ptSt, 10 * EPS_SMALL) ||
! AreSamePointEpsilon( cvClosedChain[nI][nK].ptEn, cvClosedChain[nJ][nK].ptEn, 10 * EPS_SMALL)) {
if ( ! AreSamePointEpsilon( cvClosedChain[nI][nK].ptSt, cvClosedChain[nJ][nK].ptSt, EPS_SMALL) ||
! AreSamePointEpsilon( cvClosedChain[nI][nK].ptEn, cvClosedChain[nJ][nK].ptEn, EPS_SMALL)) {
bSame = false ;
break ;
}
@@ -3254,13 +3276,13 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
}
}
}
// Recupero i loop della faccia da dividere
// Recupero i loop della faccia da dividere
vector<FacetPiece>& vNewPieces = ( NewFacet.emplace( it->first, vector<FacetPiece>()).first)->second ;
vNewPieces.emplace_back();
vNewPieces.back().nPiecePart = 1 ;
GetFacetLoops( it->first, vNewPieces.back().vPieceLoop) ;
// Divido la faccia in parti.
// Ciclo sulle catene finché non esauriscono.
// Divido la faccia in parti.
// Ciclo sulle catene finché non esauriscono.
int nIterNumber = 0 ;
int nPrevLastChainNum = int( cvOpenChain.size()) ;
while ( int( cvOpenChain.size()) > 0) {
@@ -3281,12 +3303,12 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
}
if ( int( cvOpenChain.size()) == 0)
break ;
// Ciclo su tutte le parti della faccia.
// Ciclo su tutte le parti della faccia.
int nPartLoopNum = int( vNewPieces.size()) ;
for ( int nPart = 0 ; nPart < nPartLoopNum ; ++ nPart) {
// Cerco i loop su cui la catena corrente inizia e finisce.
// Cerco i loop su cui la catena corrente inizia e finisce.
INTVECTOR vLoopIndexes ;
// Ciclo sui loop della faccia.
// Ciclo sui loop della faccia.
for ( int nLoop = 0 ; nLoop < int( vNewPieces[nPart].vPieceLoop.size()) && int( vLoopIndexes.size()) < 2 ; ++ nLoop) {
int nSegNum ;
double dParOnSeg ;
@@ -3301,47 +3323,47 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
vLoopIndexes.emplace_back( nLoop) ;
}
}
// Se non ho trovato almeno un taglio completo, vado al prossimo.
// Se non ho trovato almeno un taglio completo, vado al prossimo.
if ( int( vLoopIndexes.size()) < 2)
continue ;
// La catena finisce sul loop ove inizia. Divido la nuova parte.
// La catena finisce sul loop ove inizia. Divido la nuova parte.
if ( vLoopIndexes[0] == vLoopIndexes[1]) {
// Cambio inizio al loop iniziale.
// Cambio inizio al loop iniziale.
ChangePolyLineStart( cvOpenChain[nLastChainNum].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]]) ;
// Divido il loop della parte
// Loop1
// Divido il loop della parte
// Loop1
PolyLine NewLoop1 ;
// Inserisco i punti della catena nella PolyLine del nuovo loop.
// Inserisco i punti della catena nella PolyLine del nuovo loop.
for ( int m = 0 ; m < int( cvOpenChain[nLastChainNum].size()) ; ++ m) {
NewLoop1.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptSt) ;
if ( m == int( cvOpenChain[nLastChainNum].size()) - 1)
NewLoop1.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptEn) ;
}
// Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva.
// Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva.
PolyLine SplitLoop1, SplitLoop2 ;
SplitPolyLineAtPoint( cvOpenChain[nLastChainNum][0].ptSt,
vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]],
SplitLoop1, SplitLoop2) ;
// Aggiungo i punti precedenti il punto di frattura nella in NewLoop1.
// Aggiungo i punti precedenti il punto di frattura nella in NewLoop1.
AddPolyLineToPolyLine( NewLoop1, SplitLoop1) ;
// Loop2
// Loop2
PolyLine NewLoop2 ;
AddPolyLineToPolyLine( NewLoop2, SplitLoop2) ;
// Inserisco i punti della catena nella PolyLine del nuovo loop.
// Inserisco i punti della catena nella PolyLine del nuovo loop.
for ( int m = int( cvOpenChain[nLastChainNum].size()) - 1 ; m >= 0 ; -- m) {
NewLoop2.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptEn) ;
if ( m == 0)
NewLoop2.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptSt) ;
}
// Loop esterno coinvolto
// Loop esterno coinvolto
if ( vLoopIndexes[0] == 0) {
// Creo i pezzi nuovi, i cui loop esterni sono quelli appena definiti.
// Creo i pezzi nuovi, i cui loop esterni sono quelli appena definiti.
FacetPiece PieceInn, PieceOut ;
PieceInn.vPieceLoop.emplace_back( NewLoop1) ;
PieceInn.nPiecePart = 1 ;
PieceOut.vPieceLoop.emplace_back( NewLoop2) ;
PieceOut.nPiecePart = - 1 ;
// Assegno i loop interni del vecchio pezzo non tagliati da catene ai nuovi.
// Assegno i loop interni del vecchio pezzo non tagliati da catene ai nuovi.
for ( int nIL = 1 ; nIL < int( vNewPieces[nPart].vPieceLoop.size()) ; ++ nIL) {
if ( nIL == vLoopIndexes[0])
continue ;
@@ -3368,7 +3390,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
vNewPieces.emplace_back( PieceInn) ;
vNewPieces.emplace_back( PieceOut) ;
}
// Loop esterno non coinvolto
// Loop esterno non coinvolto
else {
Plane3d plLoopPlane1, plLoopPlane2, plContLoopPlane;
double dArea1, dArea2, dAreaCont;
@@ -3387,11 +3409,11 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
NewLoopCCW = NewLoop2;
NewLoopCW = NewLoop1;
}
// Creo il pezzo nuovo, il cui loop esterno è stato appena definito.
// Creo il pezzo nuovo, il cui loop esterno è stato appena definito.
FacetPiece DetachedPiece;
DetachedPiece.vPieceLoop.emplace_back(NewLoopCCW);
DetachedPiece.nPiecePart = bFirstLoopIsCounter ? 1 : -1;
// Al pezzo pezzo staccato assegno i loop interni del vecchio pezzo non tagliati da catene.
// Al pezzo pezzo staccato assegno i loop interni del vecchio pezzo non tagliati da catene.
for ( int nIL = 1 ; nIL < int( vNewPieces[nPart].vPieceLoop.size()) ; ++ nIL) {
if ( nIL == vLoopIndexes[0])
continue ;
@@ -3400,7 +3422,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
if ( IsPointInsidePolyLine( ptPointInnerLoop, DetachedPiece.vPieceLoop[0])) {
DetachedPiece.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ;
vNewPieces[nPart].vPieceLoop.erase( vNewPieces[nPart].vPieceLoop.begin() + nIL) ;
// Cambio il numero dei loop talgiati
// Cambio il numero dei loop tagliati
for ( int nIntersLoop = 0 ; nIntersLoop < int( vLoopIndexes.size()) ; ++ nIntersLoop) {
if ( vLoopIndexes[nIntersLoop] > nIL)
-- vLoopIndexes[nIntersLoop] ;
@@ -3408,26 +3430,26 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
-- nIL ;
}
}
// Aggiungo al pezzo, da cui si stacca quello appena creato, il loop complementare a quello che appartiene al pezzo che si stacca.
// Aggiungo al pezzo, da cui si stacca quello appena creato, il loop complementare a quello che appartiene al pezzo che si stacca.
/*if ( ! bFirstLoopIsCounter)*/
vNewPieces[nPart].vPieceLoop.erase(vNewPieces[nPart].vPieceLoop.begin() + vLoopIndexes[0]);
vNewPieces[nPart].vPieceLoop.emplace_back( NewLoopCW) ;
vNewPieces[nPart].nPiecePart = bFirstLoopIsCounter ? - 1 : 1 ;
vNewPieces.emplace_back( DetachedPiece) ;
}
// Elimino la catena usata.
// Elimino la catena usata.
cvOpenChain.erase( cvOpenChain.begin() + nLastChainNum) ;
// Interrompo il ciclo sulle parti.
// Interrompo il ciclo sulle parti.
break ;
}
// Cerco le catene per dividere la nuova parte.
// Cerco le catene per dividere la nuova parte.
else {
INTVECTOR vChainIndex ;
vChainIndex.emplace_back( nLastChainNum) ;
while ( vLoopIndexes.back() != vLoopIndexes[0]) {
// Cambio inizio del loop corrente in modo che il punto di inizio sia il punto finale dell'ultima catena trovata.
// Cambio inizio del loop corrente in modo che il punto di inizio sia il punto finale dell'ultima catena trovata.
ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()]) ;
// Cerco catene che iniziano sul loop coorente
// Cerco catene che iniziano sul loop coorente
vector<PositionOnPolyLine> vChainStartingOnLoop ;
for ( int nCh = 0 ; nCh < nLastChainNum ; ++ nCh) {
int nSegNum ;
@@ -3436,7 +3458,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
vChainStartingOnLoop.emplace_back( PositionOnPolyLine(nCh, nSegNum, dParOnSeg)) ;
}
}
// Ordino le catene secondo la vicinanza lungo il loop del loro punto d'inizio al punto d'inizio del loop stesso.
// Ordino le catene secondo la vicinanza lungo il loop del loro punto d'inizio al punto d'inizio del loop stesso.
sort( vChainStartingOnLoop.begin(), vChainStartingOnLoop.end(), [] ( PositionOnPolyLine Ch1, PositionOnPolyLine Ch2) {
if ( Ch1.nSegNum/*nIndexInVec*/ < Ch2.nSegNum/*nIndexInVec*/)
return true ;
@@ -3444,81 +3466,81 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
return Ch1.dParOnSeg < Ch2.dParOnSeg ;
else
return false ; } ) ;
// Cerco la prima catena che non termina sul loop corrente.
// Cerco la prima catena che non termina sul loop corrente.
for ( int n = 0 ; n < int( vChainStartingOnLoop.size()) ; ++ n) {
// Indice della catena e indice del segmento finale
// Indice della catena e indice del segmento finale
int nCh = vChainStartingOnLoop[n].nIndexInVec ;
int nLastLineIndex = int( cvOpenChain[nCh].size()) - 1 ;
// Ciclo sui loop
// Ciclo sui loop
int nLoopNum = int( vNewPieces[nPart].vPieceLoop.size()) ;
int nLoop ;
for ( nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) {
// Salto il loop corrente
bool bFound = false ;
for ( int nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) {
// Salto il loop corrente
if ( nLoop == vLoopIndexes.back())
continue ;
int nSegNum ;
double dParOnSeg ;
// La catena termina su questo loop diverso da quello corrente.
if ( nLoop != vLoopIndexes.back() &&
PointPositionOnPolyLine( cvOpenChain[nCh][nLastLineIndex].ptEn, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg)) {
// Salvo l'indice della catena e quello del loop.
// La catena termina su questo loop diverso da quello corrente.
if ( PointPositionOnPolyLine( cvOpenChain[nCh][nLastLineIndex].ptEn, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg)) {
// Salvo l'indice della catena e quello del loop.
vChainIndex.emplace_back( nCh) ;
vLoopIndexes.emplace_back( nLoop) ;
bFound = true ;
break ;
}
}
if ( nLoop == nLoopNum)
if ( bFound)
break ;
}
}
// Cambio inizio al loop iniziale.
// Cambio inizio al loop iniziale.
ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]]) ;
// Divido i loop della parte.
// Divido i loop della parte.
POLYLINEVECTOR vPolySecondPartVec ;
PolyLine NewLoop1 ;
for ( int n = 0 ; n < int( vChainIndex.size()) ; ++ n) {
// Inserisco i punti della catena nella PolyLine del nuovo loop.
// Inserisco i punti della catena nella PolyLine del nuovo loop.
for ( int m = 0 ; m < int( cvOpenChain[vChainIndex[n]].size()) ; ++ m) {
NewLoop1.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptSt) ;
if ( m == int( cvOpenChain[vChainIndex[n]].size()) - 1)
NewLoop1.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptEn) ;
}
// Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva.
// Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva.
PolyLine SplitLoop1, SplitLoop2 ;
SplitPolyLineAtPoint( cvOpenChain[vChainIndex[( n + 1) % int( vChainIndex.size())]][0].ptSt,
vNewPieces[nPart].vPieceLoop[vLoopIndexes[n + 1]],
SplitLoop1, SplitLoop2) ;
// Aggiungo i punti precedenti il punto di frattura in NewLoop1.
// Aggiungo i punti precedenti il punto di frattura in NewLoop1.
AddPolyLineToPolyLine( NewLoop1, SplitLoop1) ;
// Salvo la parte dopo il punto di frattura in un apposito vettore.
// Salvo la parte dopo il punto di frattura in un apposito vettore.
vPolySecondPartVec.emplace_back( SplitLoop2) ;
}
PolyLine NewLoop2 ;
for ( int n = int( vChainIndex.size()) - 1 ; n >= 0 ; -- n) {
// Aggiungo i punti successivi il punto di frattura in NewLoop2.
// Aggiungo i punti successivi il punto di frattura in NewLoop2.
AddPolyLineToPolyLine( NewLoop2, vPolySecondPartVec[n]) ;
// Inserisco i punti della catena nella PolyLine del nuovo loop.
// Inserisco i punti della catena nella PolyLine del nuovo loop.
for ( int m = int( cvOpenChain[vChainIndex[n]].size()) - 1 ; m >= 0 ; -- m) {
NewLoop2.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptEn) ;
if ( m == 0)
NewLoop2.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptSt) ;
}
}
// Controllo che il loop esterno sia interessato.
// Controllo che il loop esterno sia interessato.
bool bExtCutted = false ;
for ( int n = 0 ; n < int( vLoopIndexes.size()) && ! bExtCutted ; ++ n) {
if ( vLoopIndexes[n] == 0)
bExtCutted = true ;
}
// Loop esterno interessato
// Loop esterno interessato
if ( bExtCutted) {
// Creo i pezzi nuovi, i cui loop esterni sono quelli appena definiti.
// Creo i pezzi nuovi, i cui loop esterni sono quelli appena definiti.
FacetPiece PieceInn, PieceOut ;
PieceInn.vPieceLoop.emplace_back( NewLoop1) ;
PieceInn.nPiecePart = 1 ;
PieceOut.vPieceLoop.emplace_back( NewLoop2) ;
PieceOut.nPiecePart = - 1 ;
// Assegno i loop interni del vecchio pezzo non tagliati da catene ai nuovi.
// Assegno i loop interni del vecchio pezzo non tagliati da catene ai nuovi.
for ( int nIL = 1 ; nIL < int( vNewPieces[nPart].vPieceLoop.size()) ; ++ nIL) {
bool bUsed = false ;
for ( int nU = 0 ; nU < int( vLoopIndexes.size()) - 1 ; ++ nU) {
@@ -3548,12 +3570,12 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
}
}
}
// Aggiungo i due nuovi pezzi ed elimino quello da cui sono nati.
// Aggiungo i due nuovi pezzi ed elimino quello da cui sono nati.
vNewPieces.erase( vNewPieces.begin() + nPart) ;
vNewPieces.emplace_back( PieceInn) ;
vNewPieces.emplace_back( PieceOut) ;
}
// Loop esterno non interessato
// Loop esterno non interessato
else {
Plane3d plLoopPlane1, plLoopPlane2, plContLoopPlane ;
double dArea1, dArea2, dAreaCont ;
@@ -3572,7 +3594,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
NewLoopCCW = NewLoop2 ;
NewLoopCW = NewLoop1 ;
}
// // Creo il pezzo nuovo, il cui loop esterno è stato appena definito.
// // Creo il pezzo nuovo, il cui loop esterno è stato appena definito.
// FacetPiece PieceInn ;
// PieceInn.vPieceLoop.emplace_back( NewLoop1) ;
// PieceInn.nPiecePart = 1 ;
@@ -3599,11 +3621,11 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
// vNewPieces[nPart].vPieceLoop.emplace_back( NewLoop2) ;
// vNewPieces[nPart].nPiecePart = - 1 ;
// vNewPieces.emplace_back( PieceInn) ;
// Creo il pezzo nuovo, il cui loop esterno è stato appena definito.
// Creo il pezzo nuovo, il cui loop esterno è stato appena definito.
FacetPiece DetachedPiece ;
DetachedPiece.vPieceLoop.emplace_back( NewLoopCCW) ;
DetachedPiece.nPiecePart = bFirstLoopIsCounter ? 1 : - 1 ;
// Al pezzo che si stacca assegno i loop interni del vecchio pezzo non tagliati da catene.
// Al pezzo che si stacca assegno i loop interni del vecchio pezzo non tagliati da catene.
for ( int nIL = 1 ; nIL < int( vNewPieces[nPart].vPieceLoop.size()) ; ++ nIL) {
bool bUsed = false ;
for ( int nU = 1 ; nU < int( vLoopIndexes.size()) - 1 ; ++ nU) {
@@ -3619,7 +3641,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
if ( IsPointInsidePolyLine( ptPointInnerLoop, DetachedPiece.vPieceLoop[0])) {
DetachedPiece.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ;
vNewPieces[nPart].vPieceLoop.erase( vNewPieces[nPart].vPieceLoop.begin() + nIL) ;
// Cambio il numero dei loop talgiati
// Cambio il numero dei loop talgiati
for ( int nIntersLoop = 0 ; nIntersLoop < int( vLoopIndexes.size()) ; ++ nIntersLoop) {
if ( vLoopIndexes[nIntersLoop] > nIL)
-- vLoopIndexes[nIntersLoop] ;
@@ -3627,7 +3649,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
-- nIL ;
}
}
// Aggiungo al pezzo, da cui si stacca quello appena creato, il loop complementare a quello che appartiene al pezzo che si stacca.
// Aggiungo al pezzo, da cui si stacca quello appena creato, il loop complementare a quello che appartiene al pezzo che si stacca.
vLoopIndexes.resize(int(vLoopIndexes.size()) - 1);
sort( vLoopIndexes.begin(), vLoopIndexes.end(), [] ( int nIndex1, int nIndex2) { return nIndex1 > nIndex2 ; }) ;
for (int nLoopInd = 0; nLoopInd < int(vLoopIndexes.size()); ++nLoopInd) {
@@ -3637,23 +3659,23 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
vNewPieces[nPart].nPiecePart = bFirstLoopIsCounter ? - 1 : 1 ;
vNewPieces.emplace_back( DetachedPiece) ;
}
// Elimino catene usate.
// Elimino catene usate.
sort( vChainIndex.begin(), vChainIndex.end(), [] ( int nIndex1, int nIndex2) { return nIndex1 > nIndex2 ; }) ;
for ( int nChInd = 0 ; nChInd < int( vChainIndex.size()) ; ++ nChInd) {
cvOpenChain.erase( cvOpenChain.begin() + vChainIndex[nChInd]) ;
}
// Interrompo il ciclo sulle parti.
// Interrompo il ciclo sulle parti.
break ;
}
}
}
// Assegno i loop chiusi interni alle rispettive parti di faccia.
// Ciclo sui pezzi di facet.
// Assegno i loop chiusi interni alle rispettive parti di faccia.
// Ciclo sui pezzi di facet.
int nPieceNum = int( vNewPieces.size()) ;
for ( int nPieceN = 0 ; nPieceN < nPieceNum ; ++ nPieceN) {
// Ciclo sui loop interni
// Ciclo sui loop interni
for ( int nInnL = 0 ; nInnL < int( cvClosedChain.size()) ; ++ nInnL) {
// Trasformo il loop interno in PolyLine.
// Trasformo il loop interno in PolyLine.
PolyLine CurInnerLoop ;
CurInnerLoop.AddUPoint( 0., cvClosedChain[nInnL][0].ptSt) ;
for ( int nSeg = 0 ; nSeg < int( cvClosedChain[nInnL].size()) ; ++ nSeg) {
@@ -3663,7 +3685,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
double dArea ;
if ( ! CurInnerLoop.IsClosedAndFlat( plPlane, dArea) || dArea < EPS_SMALL)
continue ;
// Ciclo sui punti del loop interno.
// Ciclo sui punti del loop interno.
PNTULIST& LoopList = CurInnerLoop.GetUPointList() ;
for ( auto itInn = LoopList.begin() ; itInn != LoopList.end() ; ++ itInn) {
Point3d ptInnP = itInn->first ;
@@ -3678,15 +3700,15 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
AuxPolygon.FromPolyLine( CurInnerLoop) ;
Vector3d vtInnLoopNorm = AuxPolygon.GetVersN() ;
if ( vtFacetNorm * vtInnLoopNorm < 0.) {
// Aggiungo loop al pezzo.
// Aggiungo loop al pezzo.
vNewPieces[nPieceN].nPiecePart = 1 ;
vNewPieces[nPieceN].vPieceLoop.emplace_back( CurInnerLoop) ;
// Aggiungo nuovo pezzo.
// Aggiungo nuovo pezzo.
vNewPieces.emplace_back() ;
vNewPieces.back().vPieceLoop.emplace_back( CurInnerLoop) ;
vNewPieces.back().vPieceLoop.back().Invert() ;
vNewPieces.back().nPiecePart = - 1 ;
// Cerco loop interni a quello appena aggiunto
// Cerco loop interni a quello appena aggiunto
INTVECTOR vSecondLevel ;
for ( int nSI = 1 ; nSI < int( vNewPieces[nPieceN].vPieceLoop.size()) ; ++ nSI) {
PNTULIST& SecLevLoopList = vNewPieces[nPieceN].vPieceLoop[nSI].GetUPointList() ;
@@ -3698,7 +3720,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
}
}
}
// Aggiungo i loop al nuovo pezzo e li tolgo dal precedente.
// Aggiungo i loop al nuovo pezzo e li tolgo dal precedente.
for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI)
vNewPieces.back().vPieceLoop.emplace_back( vNewPieces[nPieceN].vPieceLoop[vSecondLevel[nSI]]) ;
for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI)
@@ -3706,15 +3728,15 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
break ;
}
else {
// Aggiungo loop al pezzo.
// Aggiungo loop al pezzo.
vNewPieces[nPieceN].nPiecePart = - 1 ;
vNewPieces[nPieceN].vPieceLoop.emplace_back( CurInnerLoop) ;
vNewPieces[nPieceN].vPieceLoop.back().Invert() ;
// Aggiungo nuovo pezzo.
// Aggiungo nuovo pezzo.
vNewPieces.emplace_back() ;
vNewPieces.back().vPieceLoop.emplace_back( CurInnerLoop) ;
vNewPieces.back().nPiecePart = 1 ;
// Cerco loop interni a quello appena aggiunto
// Cerco loop interni a quello appena aggiunto
INTVECTOR vSecondLevel ;
for ( int nSI = 1 ; nSI < int( vNewPieces[nPieceN].vPieceLoop.size()) ; ++ nSI) {
PNTULIST& SecLevLoopList = vNewPieces[nPieceN].vPieceLoop[nSI].GetUPointList() ;
@@ -3726,7 +3748,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
}
}
}
// Aggiungo i loop al nuovo pezzo e li tolgo dal precedente.
// Aggiungo i loop al nuovo pezzo e li tolgo dal precedente.
for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI)
vNewPieces.back().vPieceLoop.emplace_back( vNewPieces[nPieceN].vPieceLoop[vSecondLevel[nSI]]) ;
for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI)
@@ -3737,10 +3759,10 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
}
}
}
// Aggiungo al loop esterno i punti dei loop interni che lo toccano.
// Ciclo sui pezzi della faccia.
// Aggiungo al loop esterno i punti dei loop interni che lo toccano.
// Ciclo sui pezzi della faccia.
for ( int nPieceN = 0 ; nPieceN < nPieceNum ; ++ nPieceN) {
// Ciclo sui segmenti del loop esterno.
// Ciclo sui segmenti del loop esterno.
PNTULIST& ExtLoopList = vNewPieces[nPieceN].vPieceLoop[0].GetUPointList() ;
auto itSt = ExtLoopList.begin() ; auto itEn = itSt ; ++ itEn ;
for ( ; itEn != ExtLoopList.end(); ++itSt, ++itEn) {
@@ -3749,12 +3771,12 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
Vector3d vtSeg = ptEn - ptSt ;
double dSegLen = vtSeg.Len() ;
vtSeg /= dSegLen ;
// Vettore dei punti dei loop interni che stanno sul segmento del loop esterno
// Vettore dei punti dei loop interni che stanno sul segmento del loop esterno
PNTUVECTOR vPointWithOrder ;
// Ciclo sui loop interni del pezzo
// Ciclo sui loop interni del pezzo
int nInnerLoopNum = int( vNewPieces[nPieceN].vPieceLoop.size()) ;
for ( int nInnLoop = 1 ; nInnLoop < nInnerLoopNum ; ++ nInnLoop) {
// Ciclo sui punti del loop interno.
// Ciclo sui punti del loop interno.
Point3d ptInnPoint ;
bool bIsFirst = true ;
bool bContinue = vNewPieces[nPieceN].vPieceLoop[nInnLoop].GetFirstPoint( ptInnPoint) ;
@@ -3774,7 +3796,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
bContinue = vNewPieces[nPieceN].vPieceLoop[nInnLoop].GetNextPoint( ptInnPoint) ;
}
}
// Riordino i punti interni sul segmento esterno in funzione della distanza dall'origine di esso
// Riordino i punti interni sul segmento esterno in funzione della distanza dall'origine di esso
for ( int nPi = 0 ; nPi < int( vPointWithOrder.size()) - 1 ; ++ nPi) {
for ( int nPj = nPi + 1 ; nPj < int( vPointWithOrder.size()) ; ++ nPj) {
if ( vPointWithOrder[nPi].second > vPointWithOrder[nPj].second) {
@@ -3782,13 +3804,13 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet
}
}
}
// Aggiungo i punti al loop esterno
// Aggiungo i punti al loop esterno
for ( int nPi = 0 ; nPi < int( vPointWithOrder.size()) ; ++ nPi) {
itSt = ExtLoopList.emplace( itEn, vPointWithOrder[nPi]) ;
}
}
}
// Se non ho diviso la faccia, la elimino
// Se non ho diviso la faccia, la elimino
if ( int( vNewPieces.size()) == 1)
NewFacet.erase( it->first) ;
}
@@ -4168,7 +4190,7 @@ SurfTriMesh::RetriangulateFacetPieces( const PieceMap& NewFacet,
//----------------------------------------------------------------------------
bool
SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other)
SurfTriMesh::IntersectTriMeshFacets( SurfTriMesh& Other)
{
////////////////////////////////////////////////////////////////////////////////////////////////////////
static int nTime = 0 ;