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:
+199
-180
@@ -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() ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user