EgtGeomKernel:
- correzione di un errore di taglio con piani nelle surf Bezier.
This commit is contained in:
+59
-27
@@ -40,6 +40,7 @@
|
||||
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Extern/Eigen/Dense"
|
||||
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||
|
||||
|
||||
using namespace std ;
|
||||
@@ -1959,7 +1960,7 @@ SurfBezier::GetLeaves( vector<tuple<int, Point3d, Point3d>>& vLeaves) const
|
||||
//Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug
|
||||
}
|
||||
else {
|
||||
Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
|
||||
Tree.BuildTree( 100 * LIN_TOL_FINE, 0.1) ;
|
||||
}
|
||||
vector<Cell> vCells ;
|
||||
Tree.GetLeaves( vCells) ;
|
||||
@@ -2260,7 +2261,7 @@ SurfBezier::CreateTrimRegionFromCuts( ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVE
|
||||
else
|
||||
pNewTrim.Set( GetSurfFlatRegionRectangle( SBZ_TREG_COEFF * m_nSpanU, SBZ_TREG_COEFF * m_nSpanV)) ;
|
||||
|
||||
// costruisco la mappa delle intersezioni, trovando tutte le intersezioni tra i trim e i loop dei vari chunk della falr region
|
||||
// costruisco la mappa delle intersezioni, trovando tutte le intersezioni tra i trim e i loop dei vari chunk della flat region
|
||||
unordered_map<TRINT,ICCIVECTOR> mInters ;
|
||||
int nInters = 0 ;
|
||||
bool bStartFound = false ;
|
||||
@@ -2400,23 +2401,29 @@ SurfBezier::CreateTrimRegionFromCuts( ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVE
|
||||
vbAdded[nNewToAdd] = true ;
|
||||
// di questo taglio mi salvo il chunk e loop di start e end
|
||||
TRINT tiStart, tiEnd ;
|
||||
bool bStartFound = false ;
|
||||
bool bEndFound = false ;
|
||||
for (const auto& pair : mInters) {
|
||||
if ( get<2>(pair.first) == nNewToAdd ) {
|
||||
for (int p = 0 ; p < int(pair.second.size()) ; ++p) {
|
||||
if ( pair.second[p].IciB->dU < EPS_SMALL) {
|
||||
tiStart = pair.first ;
|
||||
bStartFound = true ;
|
||||
if ( bFirstCurveOfEdge){
|
||||
// salvo l'inizio del taglio che è la prima curva di questa curva compo
|
||||
tiFirstInters = pair.first ;
|
||||
bFirstCurveOfEdge = false ;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
tiEnd = pair.first ;
|
||||
bEndFound = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! bEndFound || ! bStartFound)
|
||||
return nullptr ;
|
||||
// devo trovare fino a che punto seguire il loop che ho trovato come prosecuzione del taglio corrente
|
||||
// devo quindi trovare la prossima intersezione con un taglio
|
||||
int nInters = -1 ;
|
||||
@@ -2546,6 +2553,11 @@ SurfBezier::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||
ICRVCOMPOPOVECTOR vpCCOpen ;
|
||||
ICRVCOMPOPOVECTOR vpCCClosed ;
|
||||
|
||||
////debug
|
||||
//static int a = 0 ;
|
||||
//a += 1 ;
|
||||
////debug
|
||||
|
||||
while ( chainC.GetChainFromNear( ptNear, false, vId)) {
|
||||
// creo una curva composita
|
||||
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
||||
@@ -2595,8 +2607,18 @@ SurfBezier::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||
vpCCClosed.back()->FromPolyLine( vPLTria[i]) ;
|
||||
}
|
||||
|
||||
// ora posso chiamare la costruzione dello spazio parametrico trimmato
|
||||
|
||||
////debug
|
||||
//// ora posso chiamare la costruzione dello spazio parametrico trimmato
|
||||
//if ( a == 4) {
|
||||
// vector<IGeoObj*> vObj ;
|
||||
// for ( int i = 0 ; i < int(vpCCOpen.size()) ; ++i)
|
||||
// vObj.push_back( vpCCOpen[i]->Clone()) ;
|
||||
// vObj.push_back( m_pTrimReg->Clone()) ;
|
||||
// vObj.push_back( this->Clone()) ;
|
||||
// SaveGeoObj( vObj, "D:\\Temp\\bezier\\triangolazione\\doppiaSTM\\curveOPEN.nge", 2) ;
|
||||
//}
|
||||
////debug
|
||||
|
||||
PtrOwner<ISurfFlatRegion> pSFR( CreateTrimRegionFromCuts( vpCCOpen, vpCCClosed)) ;
|
||||
if ( IsNull( pSFR) || ! pSFR->IsValid())
|
||||
return false ;
|
||||
@@ -2798,13 +2820,16 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
}
|
||||
|
||||
// se la superficie è chiusa controllo se devo tenere conto della periodicità nel prendere le coordinate parametriche dei vertici
|
||||
double dParamH, dParamL ;
|
||||
double dParamH = 0, dParamL = 0 ;
|
||||
INTVECTOR vOn(3) ;
|
||||
fill( vOn.begin(), vOn.end(), -1) ;
|
||||
bool bOneVertexOnClosureButNotPole = false ;
|
||||
if ( m_bClosedU || m_bClosedV) {
|
||||
dParamH = m_nSpanV * SBZ_TREG_COEFF ;
|
||||
dParamL = m_nSpanU * SBZ_TREG_COEFF ;
|
||||
// devo trovare il lato più lungo e confrontarlo con le dimensioni dello spazio parametrico
|
||||
Vector3d vtDir ;
|
||||
double dDist ;
|
||||
double dDist = 0 ;
|
||||
if ( DistXY( vPtPa[0], vPtPa[1]) > DistXY( vPtPa[1], vPtPa[2]) && DistXY( vPtPa[0], vPtPa[1]) > Dist( vPtPa[0], vPtPa[2])){
|
||||
vtDir = vPtPa[1] - vPtPa[0] ;
|
||||
dDist = DistXY( vPtPa[0], vPtPa[1]) ;
|
||||
@@ -2823,8 +2848,6 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
// do per scontato che se la superficie è chiusa lungo un parametro i lati di chiusura non siano dei poli
|
||||
if ( m_bClosedU && abs(vtDir.x) > abs( vtDir.y) && dDist > dParamL * 0.5 ) {
|
||||
// trovo se dei vertici del triangolo sono sul bordo dello spazio parametrico
|
||||
INTVECTOR vOn(3) ;
|
||||
fill( vOn.begin(), vOn.end(), -1) ;
|
||||
INTVECTOR vEdgesClosed = { 1, 3} ;
|
||||
// scorro sui vertici
|
||||
for ( int p = 0 ; p < 3; ++p ) {
|
||||
@@ -2839,12 +2862,12 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
}
|
||||
// controllo che almeno un vertice sia su un edge e se è l'unico vertice, che non sia su un polo
|
||||
if ( vOn[0] > 0 || vOn[1] > 0 || vOn[2] > 0) {
|
||||
// se ho più un vertice sul lato oppure se ne ho solo uno ma non è sul polo allora procedo alla correzione delle coordinate
|
||||
if ( vOn[0] * vOn[1] * vOn[2] < 0 ||
|
||||
(vOn[0] > 0 && 0 != nVertOnPole) ||
|
||||
(vOn[1] > 0 && 1 != nVertOnPole) ||
|
||||
(vOn[2] > 0 && 2 != nVertOnPole)) {
|
||||
double dRightX ;
|
||||
// se ho più di un vertice sul lato oppure se ne ho solo uno ma non è sul polo allora procedo alla correzione delle coordinate
|
||||
bOneVertexOnClosureButNotPole = (vOn[0] > 0 && 0 != nVertOnPole) ||
|
||||
(vOn[1] > 0 && 1 != nVertOnPole) ||
|
||||
(vOn[2] > 0 && 2 != nVertOnPole) ;
|
||||
if ( vOn[0] * vOn[1] * vOn[2] < 0 || bOneVertexOnClosureButNotPole) {
|
||||
double dRightX = 0 ;
|
||||
// tengo per buone le coordinate dei vertici che NON sono sul bordo dello spazio parametrico
|
||||
for ( int p = 0 ; p < 3; ++p) {
|
||||
if ( vOn[p] == -1) {
|
||||
@@ -2853,7 +2876,8 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
}
|
||||
}
|
||||
for ( int p = 0 ; p < 3; ++p) {
|
||||
if ( abs(vPtPa[p].x - dRightX) > EPS_SMALL ) {
|
||||
//if ( abs(vPtPa[p].x - dRightX) > EPS_SMALL ) {
|
||||
if ( abs(vPtPa[p].x - dRightX) > SBZ_TREG_COEFF / 2) {
|
||||
if ( vPtPa[p].x < EPS_SMALL)
|
||||
vPtPa[p].x = dParamL ;
|
||||
else
|
||||
@@ -2864,8 +2888,6 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
}
|
||||
}
|
||||
else if ( m_bClosedV && abs(vtDir.y) > abs(vtDir.x) && dDist > dParamH * 0.5) {
|
||||
INTVECTOR vOn(3) ;
|
||||
fill( vOn.begin(), vOn.end(), -1) ;
|
||||
int nVertOnPole = -1 ;
|
||||
INTVECTOR vEdgesClosed = { 0, 2} ;
|
||||
// scorro sui vertici
|
||||
@@ -2882,10 +2904,10 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
// controllo che almeno un vertice sia su un edge
|
||||
if ( vOn[0] > 0 || vOn[1] > 0 || vOn[2] > 0) {
|
||||
// se ho più un vertice sul lato oppure se ne ho solo uno ma non è sul polo allora procedo alla correzione delle coordinate
|
||||
if ( vOn[0] * vOn[1] * vOn[2] < 0 ||
|
||||
(vOn[0] > 0 && 0 != nVertOnPole) ||
|
||||
(vOn[1] > 0 && 1 != nVertOnPole) ||
|
||||
(vOn[2] > 0 && 2 != nVertOnPole)) {
|
||||
bOneVertexOnClosureButNotPole = (vOn[0] > 0 && 0 != nVertOnPole) ||
|
||||
(vOn[1] > 0 && 1 != nVertOnPole) ||
|
||||
(vOn[2] > 0 && 2 != nVertOnPole) ;
|
||||
if ( vOn[0] * vOn[1] * vOn[2] < 0 || bOneVertexOnClosureButNotPole) {
|
||||
double dRightY = 0 ;
|
||||
// tengo per buone le coordinate dei vertici che NON sono sul bordo dello spazio parametrico
|
||||
for ( int p = 0 ; p < 3; ++p) {
|
||||
@@ -2895,7 +2917,8 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
}
|
||||
}
|
||||
for ( int p = 0 ; p < 3; ++p) {
|
||||
if ( abs(vPtPa[p].y - dRightY) > EPS_SMALL) {
|
||||
//if ( abs(vPtPa[p].y - dRightY) > EPS_SMALL) {
|
||||
if ( abs(vPtPa[p].y - dRightY) > SBZ_TREG_COEFF / 2) {
|
||||
if ( vPtPa[p].y < EPS_SMALL)
|
||||
vPtPa[p].y = dParamH ;
|
||||
else
|
||||
@@ -2912,16 +2935,25 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
if ( nEdge == -1)
|
||||
return false ;
|
||||
// trovo la coordinata giusta da tenere ( x o y a seconda dell'edge)
|
||||
double dRightX, dRightY ;
|
||||
double dRightX = 0, dRightY = 0 ;
|
||||
for ( int p = 0 ; p < 3; ++p) {
|
||||
if ( p != nVertOnPole) {
|
||||
if ( nEdge == 0 || nEdge == 2) {
|
||||
dRightX = vPtPa[p].x ;
|
||||
if ( vPtPa[p].x > dRightX )
|
||||
dRightX= vPtPa[p].x ;
|
||||
// se un vertice è su un lato di chiusura, visto che sono vicino ad un polo, mi accerto che un lato del triangolo sia SUL lato di chiusura
|
||||
if( m_bClosedU && bOneVertexOnClosureButNotPole)
|
||||
dRightX = ( dParamL - vPtPa[p].x > vPtPa[p].x ? 0 : dParamL) ;
|
||||
dRightY = nEdge == 0 ? dParamH : 0 ;
|
||||
}
|
||||
else if ( nEdge == 1 || nEdge == 3) {
|
||||
// se un vertice è su un lato di chiusura, visto che sono vicino ad un polo, mi accerto che un lato del triangolo sia SUL lato di chiusura
|
||||
if( m_bClosedU && bOneVertexOnClosureButNotPole)
|
||||
dRightY = ( dParamH - vPtPa[p].y > vPtPa[p].y ? 0 : dParamH) ;
|
||||
|
||||
dRightX = nEdge == 1 ? 0 : dParamL ;
|
||||
dRightY = vPtPa[p].y ;
|
||||
if ( vPtPa[p].y < dRightY )
|
||||
dRightY = vPtPa[p].y ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2183,6 +2183,8 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
|
||||
Point3d ptCurr ;
|
||||
auto iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ;
|
||||
int nIdPolygon = distance( m_vnLeaves.begin(), iter) ;
|
||||
if ( nIdPolygon > int( vplPolygons.size()) - 1)
|
||||
return false ;
|
||||
bool bEraseNextPoint = false ;
|
||||
while ( plLoop.GetNextPoint( ptCurr)) {
|
||||
Point3d ptTStart, ptTEnd ;
|
||||
@@ -2218,6 +2220,8 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
|
||||
// ricalcolo la posizione di nId nel vettore delle foglie
|
||||
iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ;
|
||||
nIdPolygon = distance( m_vnLeaves.begin(), iter) ;
|
||||
if ( nIdPolygon > int( vplPolygons.size()) - 1)
|
||||
return false ;
|
||||
// aggiorno il puntatore alla cella
|
||||
pCell = &m_mTree[nId] ;
|
||||
// salvo il verso del loop
|
||||
|
||||
Reference in New Issue
Block a user