EgtGeomKernel 2.5k5 :

- introdotta classe per Voronoi
- aggiunto oggetto Voronoi alle curve e alla SurfFlatRegion
- introdotta la versione Voronoi in OffsetCurve e in SurfFlatRegion::Offset
- aggiunta funzione che calcola una nuova flat region offsettando una flat region esistente
- introdotta la versione Voronoi nel calcolo di una SurfFlatRegion da fat curve
- aggiunto vettore di parametri temporanei di tipo double agli oggetti geometrici.
This commit is contained in:
SaraP
2023-11-23 13:01:08 +01:00
parent b96daf4925
commit d6fffd228e
41 changed files with 2776 additions and 1000 deletions
+199 -180
View File
@@ -114,7 +114,7 @@ GetSurfFlatRegionDisk( double dRadius)
//-------------------------------------------------------------------------------
ISurfFlatRegion*
GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids)
GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids, bool bUseVoronoi)
{
// mi impossesso della curva
PtrOwner<ICurve> pCurve( pCrv) ;
@@ -124,200 +124,219 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
Vector3d vtExtr ; pCrv->GetExtrusion( vtExtr) ;
if ( vtExtr.IsSmall())
vtExtr = Z_AX ;
PtrOwner<CurveComposite> pCompo1 ;
if ( ! pCompo1.Set( ConvertCurveToBasicComposite( Release( pCurve))))
return nullptr ;
pCompo1->SetExtrusion( vtExtr) ;
// se distanza tra gli estremi minore di due volte il raggio la chiudo, purchè curva abbastanza lunga
Point3d ptStart, ptEnd, ptMid ;
Vector3d vtStart, vtEnd ;
pCompo1->GetStartPoint( ptStart) ;
pCompo1->GetStartDir( vtStart) ;
pCompo1->GetEndPoint( ptEnd) ;
pCompo1->GetEndDir( vtEnd) ;
pCompo1->GetMidPoint( ptMid) ;
if ( AreSamePointEpsilon( ptStart, ptEnd, 2 * dRadius) && Dist( ptStart, ptMid) > 2 * dRadius && Dist( ptEnd, ptMid) > 2 * dRadius) {
if ( AreSamePointEpsilon( ptStart, ptEnd, max( 0.1 * dRadius, 10 * EPS_SMALL))) {
Point3d ptNew = Media( ptStart, ptEnd) ;
pCompo1->ModifyStart( ptNew) ;
pCompo1->ModifyEnd( ptNew) ;
}
else {
// piano della curva
Frame3d frLoc ;
if ( ! AreSameVectorApprox( vtExtr, Z_AX))
frLoc.Set( ptStart, vtExtr) ;
// costruisco il biarco nel piano della curva
ptStart.ToLoc( frLoc) ;
ptEnd.ToLoc( frLoc) ;
Vector3d vtELoc( vtEnd) ; vtELoc.ToLoc( frLoc) ;
Vector3d vtSLoc( vtStart) ; vtSLoc.ToLoc( frLoc) ;
double dAngEnd ; vtELoc.ToSpherical( nullptr, nullptr, &dAngEnd) ;
double dAngStart ; vtSLoc.ToSpherical( nullptr, nullptr, &dAngStart) ;
PtrOwner<ICurve> pClose( GetBiArc( ptEnd, dAngEnd, ptStart, dAngStart, 0.5)) ;
// aggiungo il biarco
if ( ! IsNull( pClose)) {
// porto il biarco in globale
pClose->ToGlob( frLoc) ;
pCompo1->AddCurve( Release( pClose)) ;
}
else
pCompo1->Close() ;
}
}
// tipo di offset
int nOffsType = ( bSquareMids ? ICurve::OFF_EXTEND : ICurve::OFF_FILLET) ;
// se curva chiusa
if ( pCompo1->IsClosed()) {
// fondo le curve allineate
pCompo1->MergeCurves( LIN_TOL_FINE, ANG_TOL_STD_DEG) ;
// ne faccio una copia e la inverto
PtrOwner<CurveComposite> pCompo2( pCompo1->Clone()) ;
if ( IsNull( pCompo2) || ! pCompo2->Invert())
return nullptr ;
// per creare la regione
SurfFlatRegionByContours SfrCntr( false, false) ;
// offset della prima curva a destra del raggio
OffsetCurve OffsCrv1 ;
if ( ! OffsCrv1.Make( pCompo1, dRadius, nOffsType))
return nullptr ;
ICurve* pOffs1 = OffsCrv1.GetLongerCurve() ;
while ( pOffs1 != nullptr) {
SfrCntr.AddCurve( pOffs1) ;
pOffs1 = OffsCrv1.GetLongerCurve() ;
}
// offset della seconda curva a destra del raggio (è invertita rispetto alla precedente)
OffsetCurve OffsCrv2 ;
if ( ! OffsCrv2.Make( pCompo2, dRadius, nOffsType))
// ----------------- CALCOLO STANDARD --------------------------------
if ( ! bUseVoronoi) {
PtrOwner<CurveComposite> pCompo1 ;
if ( ! pCompo1.Set( ConvertCurveToBasicComposite( Release( pCurve))))
return nullptr ;
ICurve* pOffs2 = OffsCrv2.GetLongerCurve() ;
while ( pOffs2 != nullptr) {
SfrCntr.AddCurve( pOffs2) ;
pOffs2 = OffsCrv2.GetLongerCurve() ;
pCompo1->SetExtrusion( vtExtr) ;
// se distanza tra gli estremi minore di due volte il raggio la chiudo, purchè curva abbastanza lunga
Point3d ptStart, ptEnd, ptMid ;
Vector3d vtStart, vtEnd ;
pCompo1->GetStartPoint( ptStart) ;
pCompo1->GetStartDir( vtStart) ;
pCompo1->GetEndPoint( ptEnd) ;
pCompo1->GetEndDir( vtEnd) ;
pCompo1->GetMidPoint( ptMid) ;
if ( AreSamePointEpsilon( ptStart, ptEnd, 2 * dRadius) && Dist( ptStart, ptMid) > 2 * dRadius && Dist( ptEnd, ptMid) > 2 * dRadius) {
if ( AreSamePointEpsilon( ptStart, ptEnd, max( 0.1 * dRadius, 10 * EPS_SMALL))) {
Point3d ptNew = Media( ptStart, ptEnd) ;
pCompo1->ModifyStart( ptNew) ;
pCompo1->ModifyEnd( ptNew) ;
}
else {
// piano della curva
Frame3d frLoc ;
if ( ! AreSameVectorApprox( vtExtr, Z_AX))
frLoc.Set( ptStart, vtExtr) ;
// costruisco il biarco nel piano della curva
ptStart.ToLoc( frLoc) ;
ptEnd.ToLoc( frLoc) ;
Vector3d vtELoc( vtEnd) ; vtELoc.ToLoc( frLoc) ;
Vector3d vtSLoc( vtStart) ; vtSLoc.ToLoc( frLoc) ;
double dAngEnd ; vtELoc.ToSpherical( nullptr, nullptr, &dAngEnd) ;
double dAngStart ; vtSLoc.ToSpherical( nullptr, nullptr, &dAngStart) ;
PtrOwner<ICurve> pClose( GetBiArc( ptEnd, dAngEnd, ptStart, dAngStart, 0.5)) ;
// aggiungo il biarco
if ( ! IsNull( pClose)) {
// porto il biarco in globale
pClose->ToGlob( frLoc) ;
pCompo1->AddCurve( Release( pClose)) ;
}
else
pCompo1->Close() ;
}
}
// creo la regione
return SfrCntr.GetSurf() ;
}
// altrimenti
else {
// se richiesti estremi squadrati, la allungo del raggio alle due estremità
if ( bSquareEnds) {
pCompo1->ExtendStartByLen( dRadius) ;
pCompo1->ExtendEndByLen( dRadius) ;
}
// fondo le curve allineate
pCompo1->MergeCurves( LIN_TOL_FINE, ANG_TOL_STD_DEG) ;
// ne faccio una copia e la inverto
PtrOwner<CurveComposite> pCompo2( pCompo1->Clone()) ;
if ( IsNull( pCompo2) || ! pCompo2->Invert())
return nullptr ;
// creo la regione
SurfFlatRegionByContours SfrCntr( false, false) ;
// offset della prima curva a destra del raggio
OffsetCurve OffsCrv1 ;
if ( ! OffsCrv1.Make( pCompo1, dRadius, nOffsType))
return nullptr ;
ICurve* pOffs1 = OffsCrv1.GetLongerCurve() ;
if ( pOffs1 == nullptr)
return nullptr ;
pCompo1->Clear() ;
while ( pOffs1 != nullptr) {
if ( pOffs1->IsClosed())
// tipo di offset
int nOffsType = ( bSquareMids ? ICurve::OFF_EXTEND : ICurve::OFF_FILLET) ;
// se curva chiusa
if ( pCompo1->IsClosed()) {
// fondo le curve allineate
pCompo1->MergeCurves( LIN_TOL_FINE, ANG_TOL_STD_DEG) ;
// ne faccio una copia e la inverto
PtrOwner<CurveComposite> pCompo2( pCompo1->Clone()) ;
if ( IsNull( pCompo2) || ! pCompo2->Invert())
return nullptr ;
// per creare la regione
SurfFlatRegionByContours SfrCntr( false, false) ;
// offset della prima curva a destra del raggio
OffsetCurve OffsCrv1 ;
if ( ! OffsCrv1.Make( pCompo1, dRadius, nOffsType))
return nullptr ;
ICurve* pOffs1 = OffsCrv1.GetLongerCurve() ;
while ( pOffs1 != nullptr) {
SfrCntr.AddCurve( pOffs1) ;
else
pCompo1->AddCurve( pOffs1) ;
pOffs1 = OffsCrv1.GetLongerCurve() ;
}
// offset della seconda curva a destra del raggio
OffsetCurve OffsCrv2 ;
if ( ! OffsCrv2.Make( pCompo2, dRadius, nOffsType))
return nullptr ;
ICurve* pOffs2 = OffsCrv2.GetLongerCurve() ;
if ( pOffs2 == nullptr)
return nullptr ;
pCompo2->Clear() ;
while ( pOffs2 != nullptr) {
if ( pOffs2->IsClosed())
pOffs1 = OffsCrv1.GetLongerCurve() ;
}
// offset della seconda curva a destra del raggio (è invertita rispetto alla precedente)
OffsetCurve OffsCrv2 ;
if ( ! OffsCrv2.Make( pCompo2, dRadius, nOffsType))
return nullptr ;
ICurve* pOffs2 = OffsCrv2.GetLongerCurve() ;
while ( pOffs2 != nullptr) {
SfrCntr.AddCurve( pOffs2) ;
else
pCompo2->AddCurve( pOffs2) ;
pOffs2 = OffsCrv2.GetLongerCurve() ;
pOffs2 = OffsCrv2.GetLongerCurve() ;
}
// creo la regione
return SfrCntr.GetSurf() ;
}
// se estremi squadrati
if ( bSquareEnds) {
// aggiungo alla prima curva una linea che la unisca alla seconda
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
Point3d ptEnd1, ptStart2 ;
if ( IsNull( pLine) ||
! pCompo1->GetEndPoint( ptEnd1) ||
! pCompo2->GetStartPoint( ptStart2) ||
! pLine->Set( ptEnd1, ptStart2) ||
! pCompo1->AddCurve( Release( pLine)))
return nullptr ;
// unisco le due curve composite e le chiudo
if ( ! pCompo1->AddCurve( Release( pCompo2)) || ! pCompo1->Close())
return nullptr ;
}
// altrimenti estremi arrotondati
// altrimenti
else {
// aggiungo alla prima curva un arco che la unisca alla seconda
PtrOwner<CurveArc> pArc1( CreateBasicCurveArc()) ;
Point3d ptEnd1, ptStart2 ;
Vector3d vtEnd1, vtStart2 ;
if ( IsNull( pArc1) ||
! pCompo1->GetEndPoint( ptEnd1) ||
! pCompo1->GetEndDir( vtEnd1) ||
! pCompo2->GetStartPoint( ptStart2) ||
! pCompo2->GetStartDir( vtStart2))
// se richiesti estremi squadrati, la allungo del raggio alle due estremità
if ( bSquareEnds) {
pCompo1->ExtendStartByLen( dRadius) ;
pCompo1->ExtendEndByLen( dRadius) ;
}
// fondo le curve allineate
pCompo1->MergeCurves( LIN_TOL_FINE, ANG_TOL_STD_DEG) ;
// ne faccio una copia e la inverto
PtrOwner<CurveComposite> pCompo2( pCompo1->Clone()) ;
if ( IsNull( pCompo2) || ! pCompo2->Invert())
return nullptr ;
// verifico se arco tangente alla prima o alla seconda curva
if ( AreSameVectorApprox( vtEnd1, vtEnd)) {
if ( ! pArc1->Set2PVN( ptEnd1, ptStart2, vtEnd1, vtExtr) ||
! pCompo1->AddCurve( Release( pArc1)))
// creo la regione
SurfFlatRegionByContours SfrCntr( false, false) ;
// offset della prima curva a destra del raggio
OffsetCurve OffsCrv1 ;
if ( ! OffsCrv1.Make( pCompo1, dRadius, nOffsType))
return nullptr ;
ICurve* pOffs1 = OffsCrv1.GetLongerCurve() ;
if ( pOffs1 == nullptr)
return nullptr ;
pCompo1->Clear() ;
while ( pOffs1 != nullptr) {
if ( pOffs1->IsClosed())
SfrCntr.AddCurve( pOffs1) ;
else
pCompo1->AddCurve( pOffs1) ;
pOffs1 = OffsCrv1.GetLongerCurve() ;
}
// offset della seconda curva a destra del raggio
OffsetCurve OffsCrv2 ;
if ( ! OffsCrv2.Make( pCompo2, dRadius, nOffsType))
return nullptr ;
ICurve* pOffs2 = OffsCrv2.GetLongerCurve() ;
if ( pOffs2 == nullptr)
return nullptr ;
pCompo2->Clear() ;
while ( pOffs2 != nullptr) {
if ( pOffs2->IsClosed())
SfrCntr.AddCurve( pOffs2) ;
else
pCompo2->AddCurve( pOffs2) ;
pOffs2 = OffsCrv2.GetLongerCurve() ;
}
// se estremi squadrati
if ( bSquareEnds) {
// aggiungo alla prima curva una linea che la unisca alla seconda
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
Point3d ptEnd1, ptStart2 ;
if ( IsNull( pLine) ||
! pCompo1->GetEndPoint( ptEnd1) ||
! pCompo2->GetStartPoint( ptStart2) ||
! pLine->Set( ptEnd1, ptStart2) ||
! pCompo1->AddCurve( Release( pLine)))
return nullptr ;
// unisco le due curve composite e le chiudo
if ( ! pCompo1->AddCurve( Release( pCompo2)) || ! pCompo1->Close())
return nullptr ;
}
// altrimenti estremi arrotondati
else {
if ( ! pArc1->Set2PVN( ptStart2, ptEnd1, -vtStart2, vtExtr) ||
! pArc1->Invert() ||
! pCompo1->AddCurve( Release( pArc1)))
// aggiungo alla prima curva un arco che la unisca alla seconda
PtrOwner<CurveArc> pArc1( CreateBasicCurveArc()) ;
Point3d ptEnd1, ptStart2 ;
Vector3d vtEnd1, vtStart2 ;
if ( IsNull( pArc1) ||
! pCompo1->GetEndPoint( ptEnd1) ||
! pCompo1->GetEndDir( vtEnd1) ||
! pCompo2->GetStartPoint( ptStart2) ||
! pCompo2->GetStartDir( vtStart2))
return nullptr ;
// verifico se arco tangente alla prima o alla seconda curva
if ( AreSameVectorApprox( vtEnd1, vtEnd)) {
if ( ! pArc1->Set2PVN( ptEnd1, ptStart2, vtEnd1, vtExtr) ||
! pCompo1->AddCurve( Release( pArc1)))
return nullptr ;
}
else {
if ( ! pArc1->Set2PVN( ptStart2, ptEnd1, -vtStart2, vtExtr) ||
! pArc1->Invert() ||
! pCompo1->AddCurve( Release( pArc1)))
return nullptr ;
}
// aggiungo alla seconda curva un arco che la unisca alla prima
PtrOwner<CurveArc> pArc2( CreateBasicCurveArc()) ;
Point3d ptEnd2, ptStart1 ;
Vector3d vtEnd2, vtStart1 ;
if ( IsNull( pArc2) ||
! pCompo2->GetEndPoint( ptEnd2) ||
! pCompo2->GetEndDir( vtEnd2) ||
! pCompo1->GetStartPoint( ptStart1) ||
! pCompo1->GetStartDir( vtStart1))
return nullptr ;
// verifico se arco tangente alla seconda o alla prima curva
if ( AreOppositeVectorApprox( vtEnd2, vtStart)) {
if ( ! pArc2->Set2PVN( ptEnd2, ptStart1, vtEnd2, vtExtr) ||
! pCompo2->AddCurve( Release( pArc2)))
return nullptr ;
}
else {
if ( ! pArc2->Set2PVN( ptStart1, ptEnd2, -vtStart1, vtExtr) ||
! pArc2->Invert() ||
! pCompo2->AddCurve( Release( pArc2)))
return nullptr ;
}
// unisco le due curve composite
if ( ! pCompo1->AddCurve( Release( pCompo2)))
return nullptr ;
}
// aggiungo alla seconda curva un arco che la unisca alla prima
PtrOwner<CurveArc> pArc2( CreateBasicCurveArc()) ;
Point3d ptEnd2, ptStart1 ;
Vector3d vtEnd2, vtStart1 ;
if ( IsNull( pArc2) ||
! pCompo2->GetEndPoint( ptEnd2) ||
! pCompo2->GetEndDir( vtEnd2) ||
! pCompo1->GetStartPoint( ptStart1) ||
! pCompo1->GetStartDir( vtStart1))
return nullptr ;
// verifico se arco tangente alla seconda o alla prima curva
if ( AreOppositeVectorApprox( vtEnd2, vtStart)) {
if ( ! pArc2->Set2PVN( ptEnd2, ptStart1, vtEnd2, vtExtr) ||
! pCompo2->AddCurve( Release( pArc2)))
return nullptr ;
}
else {
if ( ! pArc2->Set2PVN( ptStart1, ptEnd2, -vtStart1, vtExtr) ||
! pArc2->Invert() ||
! pCompo2->AddCurve( Release( pArc2)))
return nullptr ;
}
// unisco le due curve composite
if ( ! pCompo1->AddCurve( Release( pCompo2)))
return nullptr ;
SfrCntr.AddCurve( Release( pCompo1)) ;
return SfrCntr.GetSurf() ;
}
SfrCntr.AddCurve( Release( pCompo1)) ;
return SfrCntr.GetSurf() ;
}
// ---------------------- CALCOLO CON VORONOI ------------------------------------
else {
// calcolo la fat curve con Voronoi
ICURVEPOVECTOR vFatCurves ;
if ( ! pCurve->CalcFatCurve( vFatCurves, dRadius, bSquareEnds, bSquareMids))
return nullptr ;
// costruisco la superficie a partire dalle curve
SurfFlatRegionByContours SfrCntr( false, false) ;
for ( int i = 0 ; i < ( int)vFatCurves.size() ; i++)
SfrCntr.AddCurve( Release( vFatCurves[i])) ;
return SfrCntr.GetSurf() ;
}
}
//----------------------------------------------------------------------------