Aggiunta classificazione linea rispetto a un poligono esteso

This commit is contained in:
LorenzoM
2021-05-20 17:49:25 +02:00
parent e5a45021fa
commit 561e444661
3 changed files with 168 additions and 52 deletions
+140 -47
View File
@@ -2427,11 +2427,12 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
m_OGrMgr.Clear() ;
SurfTriMesh SurfB ;
SurfB.CopyFrom( &Other) ;
Frame3d frScalingRef ;
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
IntersectTriMeshTriangle( SurfB) ;
//Frame3d frScalingRef ;
//frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
//Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
//SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
//IntersectTriMeshTriangle( SurfB) ;
ItersectTriMeshFacets( SurfB) ;
IdentifyParts() ;
SurfB.IdentifyParts() ;
int nTriaNumA = GetTriangleSize() ;
@@ -2453,11 +2454,11 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
}
}
bool bOk = ( AdjustVertices() && DoCompacting()) ;
bOk && RemoveTripleTriangles() ;
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
//bOk && RemoveTripleTriangles() ;
//bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
bOk && RemoveTJunctions() ;
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
//Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
return bOk ;
}
@@ -2811,6 +2812,136 @@ SurfTriMesh::IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& Ex
// return bOk ;
//}
static bool
GetLineExtPolygonClassification( const POLYLINEVECTOR& vContourVec, const Point3d& ptSt, const Point3d& ptEn,
CRVCVECTOR& vLinePart)
{
// Se i contorni non definiscono un poligono esteso o la retta non giace sul piano di quest'ultimo, non ha senso procedere.
double dArea ;
Plane3d plPlane ;
if ( vContourVec.empty() || ! vContourVec[0].IsClosedAndFlat( plPlane, dArea) ||
DistPointPlane( ptSt, plPlane) > EPS_SMALL || DistPointPlane( ptEn, plPlane) > EPS_SMALL)
return false ;
// Pulisco il vettore delle parti.
vLinePart.clear() ;
// Proietto tutti i punti sul piano per eliminare eventuali deviazioni.
POLYLINEVECTOR vMyContourVec ;
for ( int nC = 0 ; nC < int( vContourVec.size()) ; ++ nC) {
vMyContourVec.emplace_back() ;
Point3d ptP ;
bool bContinue = vContourVec[nC].GetFirstPoint( ptP) ;
while ( bContinue) {
vMyContourVec.back().AddUPoint( 0, ProjectPointOnPlane( ptP, plPlane)) ;
bContinue = vContourVec[nC].GetNextPoint( ptP) ;
}
}
Point3d ptMySt = ProjectPointOnPlane( ptSt, plPlane) ;
Point3d ptMyEn = ProjectPointOnPlane( ptEn, plPlane) ;
Vector3d vtLineDir = ptMyEn - ptMySt ;
double dLen = vtLineDir.Len() ;
vtLineDir /= dLen ;
// Intersezione della linea con i contoni
ICCIVECTOR vIntInfoVec ;
CurveLine cvLine ;
cvLine.Set( ptMySt, ptMyEn) ;
for ( int nC = 0 ; nC < int( vMyContourVec.size()) ; ++ nC) {
Point3d ptSegS, ptSegE ;
bool bContinue = vMyContourVec[nC].GetFirstPoint( ptSegS) && vMyContourVec[nC].GetNextPoint( ptSegE) ;
while ( bContinue) {
vMyContourVec.back().AddUPoint( 0, ProjectPointOnPlane( ptP, plPlane)) ;
CurveLine cvSeg ;
cvSeg.Set( ptMySt, ptMyEn) ;
IntersLineLine( cvLine, cvSeg) ;
IntCrvCrvInfo aInfo ;
if ( IntersLineLine.GetIntCrvCrvInfo(aInfo)) ;
vIntInfoVec.emplace_back( aInfo) ;
ptSegS = ptSegE ;
bContinue = vMyContourVec[nC].GetNextPoint( ptSegE) ;
}
}
// Riordino le intersezioni e unisco le parti sovrapposte.
sort( vIntInfoVec.begin(), vIntInfoVec.end(), [] ( IntCrvCrvInfo Int1, IntCrvCrvInfo Int2) { return Int1.IciA[0] < Int2.IciA[0] ; }) ;
for ( int n = 0 ; n < int( vIntInfoVec.size()) - 1 ; ++ n) {
for ( int m = n + 1 ; vIntInfoVec[n].bOverlap && m < int( vIntInfoVec.size()) ; ++ m) {
if ( vIntInfoVec[n].IciA[1] > vIntInfoVec[m].IciA[0]) {
if ( vIntInfoVec[m].bOverlap && vIntInfoVec[n].IciA[1] < vIntInfoVec[m].IciA[1]) {
vIntInfoVec[n].IciA[1] = vIntInfoVec[m].IciA[1] ;
}
vIntInfoVec.erase( vIntInfoVec.begin() + m) ;
-- m ;
}
}
}
// Definisco le parti di linea dentro il poligono esteso.
bool bStateInside = true ;
for ( int nC = 0 ; nC < int( vMyContourVec.size()) ; ++ nC) {
bStateInside = bStateInside || IsPointInsidePolyLine( ptMySt, vMyContourVec[nC]) ;
}
if ( bStateInside)
vLinePart.emplace_back( 0, -1, LCP_ERROR) ;
for ( int n = 0 ; n < int( vIntInfoVec.size()) ; ++ n) {
// La linea è dentro.
if ( bStateInside) {
// Segno che chiudiamo una parte d'intersezione.
bStateInside = false ;
// L'intersezione corrente è un segmento.
if ( vIntInfoVec[n].bOverlap) {
// Si chiude la parte precedente e si aggiunge un segmeno
if ( vIntInfoVec[n].IciA[0] > vLinePart.back().dParS + EPS_SMALL) {
vLinePart.back().dParE = vLinePart.back().dParS ;
vLinePart.back().nClass = LCP_OVERLAP ;
vLinePart.emplace_back( vIntInfoVec[n].IciA[0], vIntInfoVec[n].IciA[1], LCP_OVERLAP) ;
}
// Si promuove l'intersezione precedente a un segmento.
else {
vLinePart.back().dParE = vIntInfoVec[n].IciA[1] ;
vLinePart.back().nClass = LCP_OVERLAP ;
}
}
// L'intersezione corrente è un punto: chiudiamo la parte precedente.
else {
vLinePart.back().dParE = vIntInfoVec[n].IciA[0] ;
vLinePart.back().nClass = LCP_INN ;
}
}
// La linea è fuori
else {
// L'intersezione corrente è un segmento.
if ( vIntInfoVec[n].bOverlap) {
// Apro e chiudo una nuova parte.
vLinePart.emplace_back( vIntInfoVec[n].IciA[0], vIntInfoVec[n].IciA[1], CRVC_ON_P) ;
}
// L'intersezione corrente è un punto: chiudiamo la parte precedente.
else {
// Segno che apro una nuova parte.
bStateInside = true ;
// Apro una nuova parte.
vLinePart.emplace_back( vIntInfoVec[n].IciA[0], - Infinito, LCP_INN) ;
}
}
}
// Controllo che non ci siano incongruenze: se tutti gli ingressi
// e le uscite sono ordinate, dovrebbe essere tutto ok.
for ( int n = 0 ; n < int( vLinePart.size()) ; ++ n) {
if ( vLinePart[n].dParS > vLinePart[n].dParE)
return false ;
if ( n + 1 < int( vLinePart.size()) && vLinePart[n].dParE > vLinePart[n + 1].dParS)
return false ;
/*for ( int m = n + 1 ; m < int( vLinePart.size()) ; ++ m) {
if ( vLinePart[n].dParE > vLinePart[m].dParS)
return false ;
}*/
}
return true ;
}
//----------------------------------------------------------------------------
static bool
ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop)
@@ -3192,14 +3323,12 @@ bool
SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet)
{
for ( auto it = IntersLineMap.begin() ; it != IntersLineMap.end() ; ++ it) {
if (it->first == 5591)
int qqq = 0;
// Normale alla faccia
Vector3d vtFacetNorm ;
GetFacetNormal( it->first, vtFacetNorm) ;
// Creo i loop
ChainCurves LoopCreator ;
LoopCreator.Init( false, 10 * EPS_SMALL, int( it->second.size()), 10) ;
LoopCreator.Init( false, 10 * EPS_SMALL, int( it->second.size()), 10 /** BOOLEAN_SCALE*/) ;
// Carico le curve per concatenarle
for ( int nCv = 0 ; nCv < int( it->second.size()); ++ nCv) {
Point3d ptSt = it->second[nCv].ptSt ;
@@ -4606,10 +4735,6 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other)
int nFacetNumA = GetFacetCount() ;
int nFacetNumB = SurfB.GetFacetCount() ;
for ( int nFA = 0 ; nFA < nFacetNumA ; ++ nFA) {
/////////////////////////////////////////////////////////
if (nFA == 129)
int mimi = 0;
/////////////////////////////////////////////////////////
// Dati della faccia
POLYLINEVECTOR LoopVecA ;
GetFacetLoops( nFA, LoopVecA) ;
@@ -4778,22 +4903,6 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other)
}
}
/////////////////////////////////////////////////////////////////////////////////
for ( int nFB = 0 ; nFB < nFacetNumB ; ++ nFB) {
// Dati della faccia
POLYLINEVECTOR LoopVecB ;
SurfB.GetFacetLoops( nFB, LoopVecB) ;
PtrOwner<SurfFlatRegion> pRegB( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( LoopVecB))) ;
if ( pRegB == nullptr)
return false ;
SurfFlatRegion RegionB = *pRegB ;
/*Plane3d plPlaneB ;*/
/*plPlaneB.Set( RegionB.GetPlanePoint(), RegionB.GetNormVersor()) ;*/
if (RegionB.GetNormVersor().x > 0.99)
int m = 0;
}
/////////////////////////////////////////////////////////////////////////////////
// Divido le facce
PieceMap NewFacetA, NewFacetB ;
SplitFacet( IntersLineMapA, NewFacetA) ;
@@ -5010,18 +5119,6 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other)
frIntersRegion.Intersect( RegionB) ;
double dIntersRegArea ;
frIntersRegion.GetArea( dIntersRegArea) ;
/*bool bOverlap = dIntersRegArea > EPS_SMALL ;
double dRegionAreaA ;
RegionA.GetArea( dRegionAreaA) ;
double dRegionAreaB ;
RegionB.GetAera( dRegionAreaB) ;
if ( ( abs( dIntersRegArea - dRegionAreaA) < EPS_SMALL && dRegionAreaA < 0.75 * dRegionAreaB) ||
( abs( dIntersRegArea - dRegionAreaB) < EPS_SMALL && dRegionAreaB < 0.75 * dRegionAreaA)) {
if ( )
bOverlap = ;
else
bOverlap = ;
}*/
// Assegno indice di parte al pezzo di faccia A e ai triangoli della faccia B.
if ( dIntersRegArea > EPS_SMALL) {
bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ;
@@ -5098,10 +5195,6 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other)
if ( n == int( vFacetIndexesB.size()))
vFacetIndexesB.emplace_back( nF) ;
}
/////////////////////////////////////////////////////////
if (nFA == 129)
int mimi = 0;
/////////////////////////////////////////////////////////
// Ciclo sulle facce di B
for ( int& nFB : vFacetIndexesB) {
auto itFacetB = NewFacetB.find( nFB) ;