Merge branch 'MoreBezier'

This commit is contained in:
Daniele Bariletti
2024-09-04 15:50:24 +02:00
6 changed files with 112 additions and 47 deletions
+4
View File
@@ -604,6 +604,10 @@ CurveComposite::CopyFrom( const CurveComposite& ccSrc)
if ( ! AddCurve( *pCrv))
return false ;
}
if ( ccSrc.m_nStatus == IS_A_POINT) {
m_ptStart = ccSrc.m_ptStart ;
m_nStatus = IS_A_POINT ;
}
return true ;
}
+2 -12
View File
@@ -72,19 +72,13 @@ GetSurfBezierByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
}
Vector3d vtN ;
INTMATRIX vnPLIndMat ;
if ( ! CalcRegionPolyLines( vPL, vPLOrd, vtN, vnPLIndMat))
BOOLVECTOR vbInvert ;
if ( ! CalcRegionPolyLines( vPL, vPLOrd, vtN, vnPLIndMat,vbInvert))
return nullptr ;
//for ( int i = 0 ; i < int(vpCurve.size()) ; ++i ) {
// PolyLine pl ;
// vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, pl) ;
// vPL.push_back( pl) ;
//}
// creo e setto la superficie di bezier
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
if ( IsNull( pSbz) || ! pSbz->CreateByRegion( vPLOrd))
return nullptr ;
//// salvo tolleranza lineare usata
//pSbz->SetLinearTolerance( dLinTol) ;
// restituisco la superficie
return Release( pSbz) ;
}
@@ -143,8 +137,6 @@ GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
// //if ( ! pSbz->DoSewing( STM1) || ! pSTM->DoSewing( STM2))
// // return nullptr ;
//}
//// salvo tolleranza lineare usata
//pSbz->SetLinearTolerance( dLinTol) ;
// restituisco la superficie
return Release( pSbz) ;
}
@@ -188,8 +180,6 @@ GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
// if ( ! SbzLat.CreateByExtrusion( vPL[i], vtExtr)) // qui mi serve la curva e non la polyline della curva. vuol dire che dalla CalcRegionPolyLines devo farmi restituire anche le curve ordinate
// return nullptr ;
// }
// //// salvo tolleranza lineare usata
// //pSTM->SetLinearTolerance( dLinTol) ;
// // restituisco la superficie
// return Release( pSrfCompo) ; // in realtà dovrei restituire tre superfici!!! due basi e una sup laterale( e quindi fare una SurfCompo) oppure dovrei spezzare le basi in tot pezzi e creare una superficie unica
//}
+8 -2
View File
@@ -575,7 +575,7 @@ SurfFlatRegionByContours::GetUnusedCurveTempProps( INTVECTOR& vId)
//-------------------------------------------------------------------------------
bool
CalcRegionPolyLines( const POLYLINEVECTOR& vPL, POLYLINEVECTOR& vPLOrd, Vector3d& vtN, INTMATRIX& vnPLIndMat)
CalcRegionPolyLines( const POLYLINEVECTOR& vPL, POLYLINEVECTOR& vPLOrd, Vector3d& vtN, INTMATRIX& vnPLIndMat, BOOLVECTOR& vbInvert)
{
// matrice di interi : ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
// successive i loop interni
@@ -638,6 +638,8 @@ CalcRegionPolyLines( const POLYLINEVECTOR& vPL, POLYLINEVECTOR& vPLOrd, Vector3d
bool bFirstCrv ;
Plane3d plExtLoop ;
double dAreaExtLoop = 0. ;
vbInvert.resize( vPL.size()) ;
fill( vbInvert.begin(), vbInvert.end(), false) ;
do {
bFirstCrv = true ;
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
@@ -655,6 +657,7 @@ CalcRegionPolyLines( const POLYLINEVECTOR& vPL, POLYLINEVECTOR& vPLOrd, Vector3d
vPLOrd[j].Invert() ;
vCrvCompo[j]->Invert() ;
dAreaExtLoop *= -1 ;
vbInvert[j] = true ;
}
bFirstCrv = false ;
}
@@ -689,6 +692,7 @@ CalcRegionPolyLines( const POLYLINEVECTOR& vPL, POLYLINEVECTOR& vPLOrd, Vector3d
if ( m_vArea[i].second * dAreaExtLoop > 0.) {
vPLOrd[j].Invert() ;
vCrvCompo[j]->Invert() ;
vbInvert[j] = true ;
}
}
}
@@ -696,8 +700,10 @@ CalcRegionPolyLines( const POLYLINEVECTOR& vPL, POLYLINEVECTOR& vPLOrd, Vector3d
} while ( ! bFirstCrv) ;
if ( bInvertAll) {
for ( int i = 0 ; i < int( vPLOrd.size()) ; ++i)
for ( int i = 0 ; i < int( vPLOrd.size()) ; ++i) {
vPLOrd[i].Invert() ;
vbInvert[i] = ! vbInvert[i] ;
}
}
//// ordino le PolyLine per area
+4 -2
View File
@@ -69,7 +69,8 @@ GetSurfTriMeshByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
}
Vector3d vtN ;
INTMATRIX vnPLIndMat ;
if ( ! CalcRegionPolyLines( vPL, vPLOrd, vtN, vnPLIndMat))
BOOLVECTOR vbInvert ;
if ( ! CalcRegionPolyLines( vPL, vPLOrd, vtN, vnPLIndMat, vbInvert))
return nullptr ;
// creo e setto la superficie trimesh
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
@@ -156,7 +157,8 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
}
Vector3d vtN ;
INTMATRIX vnPLIndMat ;
if ( ! CalcRegionPolyLines( vPL, vPLOrd, vtN, vnPLIndMat))
BOOLVECTOR vbInvert ;
if ( ! CalcRegionPolyLines( vPL, vPLOrd, vtN, vnPLIndMat, vbInvert))
return nullptr ;
// verifico la direzione di estrusione
double dOrthoExtr = vtN * vtExtr ;
+92 -30
View File
@@ -632,8 +632,21 @@ SurfBezier::CopyFrom( const SurfBezier& sbSrc)
m_bTrimmed = true ;
m_pTrimReg = sbSrc.m_pTrimReg->Clone() ;
}
if ( sbSrc.m_pSTM != nullptr)
if ( sbSrc.m_pSTM != nullptr) {
m_pSTM = sbSrc.m_pSTM->Clone() ;
for ( int i = 0 ; i < int( sbSrc.m_mCCEdge.size()) ; ++i) {
m_mCCEdge.emplace_back() ;
for ( int j = 0 ; j < int( sbSrc.m_mCCEdge[i].size()) ; ++j ) {
m_mCCEdge.back().emplace_back( sbSrc.m_mCCEdge[i][j]->Clone()) ;
}
}
if( sbSrc.m_bTrimmed) {
for ( int i = 0 ; i < int( sbSrc.m_vCCLoop.size()) ; ++i)
m_vCCLoop.emplace_back( sbSrc.m_vCCLoop[i]->Clone());
}
}
m_bClosedU = sbSrc.m_bClosedU ;
m_bClosedV = sbSrc.m_bClosedV ;
m_nTempProp[0] = sbSrc.m_nTempProp[0] ;
m_nTempProp[1] = sbSrc.m_nTempProp[1] ;
m_dTempParam[0] = sbSrc.m_dTempParam[0] ;
@@ -1883,6 +1896,9 @@ SurfBezier::ResetAuxSurf( void) const
if ( m_pSTM != nullptr)
delete( m_pSTM) ;
m_pSTM = nullptr ;
m_mCCEdge.clear() ;
m_vCCLoop.clear() ;
}
//----------------------------------------------------------------------------
@@ -1896,6 +1912,9 @@ SurfBezier::ResetTrimRegion( void)
m_bTrimmed = false ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
m_mCCEdge.clear() ;
m_vCCLoop.clear() ;
}
//----------------------------------------------------------------------------
@@ -2024,9 +2043,10 @@ SurfBezier::UnprojectCurveFromStm( const ICurveComposite* pCC, ICRVCOMPOPVECTOR&
}
Vector3d vtDir = pt2D - pt2DPrev ;
vtDir.Normalize() ;
// se mi accorgo che sto per tracciare un taglio lungo un bordo posso semplicmente evitarlo
if ( (1 - abs(vtDir.x) < SQ_EPS_SMALL && (pt2D.y < 1 || m_nSpanV * SBZ_TREG_COEFF - pt2D.y < 1)) || // parallelo agli edge 0 e 2 e su uno di questi
(1 - abs(vtDir.y) < SQ_EPS_SMALL && (pt2D.x < 1 || m_nSpanU * SBZ_TREG_COEFF - pt2D.x < 1))) { // parallello agli edge 1 e 3 e su uno di questi
// se mi accorgo che sto per tracciare un taglio lungo un bordo posso semplicemente evitarlo
double dDelta = 10 * EPS_SMALL ;
if ( (1 - abs(vtDir.x) < SQ_EPS_SMALL && (pt2D.y < dDelta || m_nSpanV * SBZ_TREG_COEFF - pt2D.y < dDelta)) || // parallelo agli edge 0 e 2 e su uno di questi
(1 - abs(vtDir.y) < SQ_EPS_SMALL && (pt2D.x < dDelta || m_nSpanU * SBZ_TREG_COEFF - pt2D.x < dDelta))) { // parallello agli edge 1 e 3 e su uno di questi
++ nRejected ;
continue ;
}
@@ -2359,6 +2379,22 @@ SurfBezier::CreateTrimRegionFromCuts( ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVE
}
}
// devo verificare se devo aggiungere anche il bordo ( basta verificare se il primo loop chiuso è CCW)
double dArea ;
if( vpCCClosed.size() != 0) {
vpCCClosed[0]->GetAreaXY( dArea) ;
if ( dArea < EPS_SMALL ) {
PolyLine plEdge ;
plEdge.AddUPoint( 0, ORIG) ;
plEdge.AddUPoint( 1, Point3d( m_nSpanU * SBZ_TREG_COEFF, 0)) ;
plEdge.AddUPoint( 2, Point3d( m_nSpanU * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF)) ;
plEdge.AddUPoint( 3, Point3d( 0, m_nSpanV * SBZ_TREG_COEFF)) ;
plEdge.Close() ;
vpCCClosed.emplace_back( CreateCurveComposite()) ;
vpCCClosed.back()->FromPolyLine( plEdge) ;
}
}
// aggiungo i loop chiusi
for ( int i = 0 ; i < int( vpCCClosed.size()); ++i )
sfrContour.AddCurve( Release( vpCCClosed[i])) ;
@@ -2595,7 +2631,8 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
}
// se ho tre intersezioni vuol dire che un lato è collassato in un punto e il punto di cui voglio la controimmagine è esattamente nel polo
if ( nInters == 3 || ( m_bClosedU && ( vInters[1] == 1 || vInters[3] == 1)) || ( m_bClosedV && ( vInters[1] == 1 || vInters[3] == 1))) {
// oppure sono su un lato di chiusura
if ( nInters == 3 || ( m_bClosedU && ( vInters[1] == 1 || vInters[3] == 1)) || ( m_bClosedV && ( vInters[0] == 1 || vInters[2] == 1))) {
if ( nInters == 3)
bIsPole = true ;
// visto che sono in un polo o su un lato di chiusura devo verificare di aver ricevuto il triangolo giusto
@@ -2902,6 +2939,8 @@ SurfBezier::UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d
vtDir.Set( - dfdU, - dfdV, 0) ;
if ( ! vtDir.Normalize() )
vtDir.Set( - dfdU / dSSum, - dfdV / dSSum, 0) ;
if( ! vtDir.IsValid())
return false ;
dr = dDistPre / dASum ;
// in modalità Retry riduco lo spostamento
vtDir *= dr * ( bRetry ? 0.1 : 0.5) ;
@@ -3529,46 +3568,50 @@ SurfBezier::CreateByFlatContour( const PolyLine& PL)
double dArea = 0 ;
if ( ! PL.IsClosedAndFlat( plPlane, dArea, EPS_SMALL))
return false ;
// porto la polyline nel frame del suo piano per trovare gli estremi della sua box in quel piano
Frame3d frContour ;
frContour.Set( plPlane.GetPoint(), plPlane.GetVersN()) ;
PolyLine plFlat = PL ;
plFlat.ToLoc( frContour) ;
// creo una superficie piana grande come il box della curva nel suo piano e poi la trimmo
// recupero il box
BBox3d bboxContour ;
PL.GetLocalBBox( bboxContour) ;
plFlat.GetLocalBBox( bboxContour) ;
// inizializzo la superficie come una bezier di primo grado formata da una sola patch
int nDegU = 1, nDegV = 1, nSpanU = 1, nSpanV = 1 ;
bool bRat = false ;
Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
// i punti di controllo sono i quattro vertici della bbox proiettata sul piano della polyline
double dPlus = 1 ;
bboxContour.Expand( dPlus) ;
Point3d ptBL = ProjectPointOnPlane(bboxContour.GetMin(), plPlane) ;
Point3d ptTR = ProjectPointOnPlane(bboxContour.GetMax(), plPlane) ;
bboxContour.Expand( dPlus, dPlus, 0) ;
Point3d ptBL = bboxContour.GetMin() ;
Point3d ptTR = bboxContour.GetMax() ;
Point3d ptTl = Point3d( ptBL.x, ptTR.y) ;
Point3d ptBr = Point3d( ptTR.x, ptBL.y) ;
ptBL.ToGlob( frContour) ;
ptTR.ToGlob( frContour) ;
ptTl.ToGlob( frContour) ;
ptBr.ToGlob( frContour) ;
SetControlPoint( 0, ptBL) ;
SetControlPoint( 1, Point3d( ptTR.x, ptBL.y)) ;
SetControlPoint( 2, Point3d( ptBL.x, ptTR.y)) ;
SetControlPoint( 1, ptBr) ;
SetControlPoint( 2, ptTl) ;
SetControlPoint( 3, ptTR) ;
// calcolo il corrispondente parametrico del contorno
//// calcolo il corrispondente parametrico del contorno
PtrOwner<ICurveComposite> pCCContour( CreateCurveComposite()) ;
if ( IsNull( pCCContour))
if ( IsNull( pCCContour) || ! pCCContour->FromPolyLine( PL) || ! pCCContour->IsValid())
return false ;
pCCContour->FromPolyLine( PL) ;
ICRVCOMPOPVECTOR vpCCParam ;
UnprojectCurveFromStm( pCCContour, vpCCParam, &plPlane) ;
// calcolo gli eventuali poli, necessari per poter chiamare le funzioni di unproject
CalcPoles() ;
ICRVCOMPOPOVECTOR vCCOpen ;
ICRVCOMPOPOVECTOR vCCClosed ;
for( int i = 0 ; i < int( vpCCParam.size()) ; ++i )
AddCurveCompoToCuts( vpCCParam[i], vCCOpen, vCCClosed) ;
AddCurveCompoToCuts( pCCContour, vCCOpen, vCCClosed) ;
// creo la regione di trim dai loop di trim
PtrOwner<ISurfFlatRegion> pSfrTrim( CreateTrimRegionFromCuts( vCCOpen, vCCClosed)) ;
if ( IsNull( pSfrTrim) || ! pSfrTrim->IsValid())
return false ;
SetTrimRegion( *pSfrTrim) ;
if ( plPlane.GetVersN().z < EPS_SMALL)
Invert() ;
// aggiorno lo stato
m_nStatus = OK ;
@@ -3579,26 +3622,44 @@ SurfBezier::CreateByFlatContour( const PolyLine& PL)
bool
SurfBezier::CreateByRegion( const POLYLINEVECTOR& vPL)
{
// le polyline in input devono essere già ordinate per area
// la prima polyline quindi è il loop più esterno
// le polyline in input devono essere già ordinate per area e orientate con il verso giusto ( tenendo conto di chunk e isole)
// la prima polyline quindi è il loop esterno del chunk più grande
Plane3d plPlane ;
double dArea = 0 ;
if ( ! vPL[0].IsClosedAndFlat(plPlane, dArea, EPS_SMALL) )
return false ;
// porto la polyline nel frame del suo piano per trovare gli estremi della sua box in quel piano
Frame3d frContour ;
frContour.Set( plPlane.GetPoint(), plPlane.GetVersN()) ;
// creo una superficie piana grande come il box della curva nel suo piano e poi la trimmo
// recupero il box
POLYLINEVECTOR vPLFlat = vPL ;
BBox3d bboxContour ;
vPL[0].GetLocalBBox(bboxContour) ;
for( int i = 0 ; i < int( vPLFlat.size()) ; ++i) {
// porto le polilinee nel riferimento del loro piano e ne recupero il box
vPLFlat[i].ToLoc(frContour) ;
BBox3d bboxLoop ;
vPLFlat[i].GetLocalBBox(bboxLoop) ;
bboxContour.Add( bboxLoop) ;
}
// inizializzo la superficie come una bezier di primo grado formata da una sola patch
int nDegU = 1, nDegV = 1, nSpanU = 1, nSpanV = 1 ;
bool bRat = false ;
Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
// i punti di controllo sono i quattro vertici della bbox ( che è piana)
double dPlus = 1 ;
bboxContour.Expand( dPlus, dPlus, 0) ;
Point3d ptBL = bboxContour.GetMin() ;
Point3d ptTR = bboxContour.GetMax() ;
Point3d ptTl = Point3d( ptBL.x, ptTR.y) ;
Point3d ptBr = Point3d( ptTR.x, ptBL.y) ;
ptBL.ToGlob( frContour) ;
ptTR.ToGlob( frContour) ;
ptTl.ToGlob( frContour) ;
ptBr.ToGlob( frContour) ;
SetControlPoint( 0, ptBL) ;
SetControlPoint( 1, Point3d( ptTR.x, ptBL.y)) ;
SetControlPoint( 2, Point3d( ptBL.x, ptTR.y)) ;
SetControlPoint( 1, ptBr) ;
SetControlPoint( 2, ptTl) ;
SetControlPoint( 3, ptTR) ;
// creo i vettori dei tagli aperti e chiusi
CalcPoles() ;
@@ -3606,7 +3667,8 @@ SurfBezier::CreateByRegion( const POLYLINEVECTOR& vPL)
ICRVCOMPOPOVECTOR vCCClosed ;
for ( int i = 0 ; i < int( vPL.size()) ; ++i) {
ICurveComposite* pCC( CreateBasicCurveComposite()) ;
pCC->FromPolyLine( vPL[i]) ;
if( pCC == nullptr || ! pCC->FromPolyLine( vPL[i]) || ! pCC->IsValid())
return false ;
if ( ! AddCurveCompoToCuts( pCC, vCCOpen, vCCClosed))
return false ; // o metto un continue?
}
@@ -3616,8 +3678,8 @@ SurfBezier::CreateByRegion( const POLYLINEVECTOR& vPL)
return false ;
SetTrimRegion( *pSfrTrim) ;
if ( plPlane.GetVersN().z < EPS_SMALL)
Invert() ;
//if ( plPlane.GetVersN().z < EPS_SMALL)
// Invert() ;
// aggiorno lo stato
m_nStatus = OK ;
+2 -1
View File
@@ -243,8 +243,9 @@ Triangulate::MakeAdvanced( const POLYLINEVECTOR& vPLORIG, PNTVECTOR& vPt, INTVEC
Vector3d vtN ;
// se non sono stati passate le info per ordinare le polyline allora le ordino
INTMATRIX vnPLIndMat ;
BOOLVECTOR vbInvert ;
if( vnPLIndMatPre.size() == 0){
if ( ! CalcRegionPolyLines( vPLORIG, vPL, vtN, vnPLIndMat))
if ( ! CalcRegionPolyLines( vPLORIG, vPL, vtN, vnPLIndMat, vbInvert))
return false ;
}
else {