EgtGeomKernel :
- In calcPocketing migliorate e semplificate le gestioni dei lati aperti, sia di bordi che di isole, anche con la superficie limite.
This commit is contained in:
+95
-125
@@ -389,7 +389,7 @@ GetCoeffLinArc( const ICurveArc* pArc, double dDiam, double& dSubArc)
|
||||
|
||||
// creo l'ombra del tool nel punto medio
|
||||
PtrOwner<ICurveArc> pCrvTool( CreateCurveArc()) ;
|
||||
pCrvTool->Set( ptMid, Z_AX, dDiam) ;
|
||||
pCrvTool->Set( ptMid, Z_AX, dDiam / 2) ;
|
||||
if ( ! pCrvTool->IsValid())
|
||||
return false ;
|
||||
|
||||
@@ -919,109 +919,7 @@ CreateSurfFrIncidence( const ICurveComposite* pCrv, const Vector3d& vtTanS_, con
|
||||
return pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0 ;
|
||||
}
|
||||
|
||||
// 1) ***
|
||||
// La regione di incidenza non deve avere un bordo distante dRad dagli estremi del tratto aperto
|
||||
// per questo motivo, creo due FlatRegion a rettangolo che andrò a sottrarre alla pSfrInc_tmp
|
||||
// ( tolgo i semi-dischi agli estremi )
|
||||
|
||||
// 2) ***
|
||||
// La regione di incidenza deve seguire seguire in tangenza il percorso agli estremi del tratto
|
||||
// aperto corrente, creo due FlatRegion a rettangolo, orientate come le tangenza dei chiusi che andrò
|
||||
// a sottrarre alla pSfrInc_tmp
|
||||
|
||||
|
||||
// 1) ***
|
||||
|
||||
// Rettangolo all'inizio
|
||||
Vector3d vtTanS ; pCrv->GetStartDir( vtTanS) ;
|
||||
Point3d ptS ; pCrv->GetStartPoint( ptS) ;
|
||||
Vector3d vtOut = vtTanS ; vtOut.Rotate( Z_AX, - 90) ;
|
||||
PtrOwner<ICurveComposite> pCrvRectSBorder( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvRectSBorder))
|
||||
return false ;
|
||||
pCrvRectSBorder->AddPoint( ptS + ( dRad + 500 * EPS_SMALL) * vtOut) ;
|
||||
pCrvRectSBorder->AddLine( ptS - ( dRad + 500 * EPS_SMALL) * vtOut) ;
|
||||
pCrvRectSBorder->AddLine( ptS - ( dRad + 500 * EPS_SMALL) * vtOut - vtTanS * ( dRad + 500 * EPS_SMALL)) ;
|
||||
pCrvRectSBorder->AddLine( ptS + ( dRad + 500 * EPS_SMALL) * vtOut - vtTanS * ( dRad + 500 * EPS_SMALL)) ;
|
||||
pCrvRectSBorder->Close() ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrRectStart( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrRectStart) ||
|
||||
! pSfrRectStart->AddExtLoop( Release( pCrvRectSBorder)) ||
|
||||
! pSfrRectStart->IsValid())
|
||||
return false ;
|
||||
if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectStart->GetNormVersor()))
|
||||
pSfrRectStart->Invert() ;
|
||||
|
||||
// Rettangolo alla fine
|
||||
Vector3d vtTanE ; pCrv->GetEndDir( vtTanE) ;
|
||||
Point3d ptE ; pCrv->GetEndPoint( ptE) ;
|
||||
vtOut = vtTanE ; vtOut.Rotate( Z_AX, - 90) ;
|
||||
PtrOwner<ICurveComposite> pCrvRectEBorder( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvRectEBorder))
|
||||
return false ;
|
||||
pCrvRectEBorder->AddPoint( ptE + ( dRad + 500 * EPS_SMALL) * vtOut) ;
|
||||
pCrvRectEBorder->AddLine( ptE - ( dRad + 500 * EPS_SMALL) * vtOut) ;
|
||||
pCrvRectEBorder->AddLine( ptE - ( dRad + 500 * EPS_SMALL) * vtOut + vtTanE * ( dRad + 500 * EPS_SMALL)) ;
|
||||
pCrvRectEBorder->AddLine( ptE + ( dRad + 500 * EPS_SMALL) * vtOut + vtTanE * ( dRad + 500 * EPS_SMALL)) ;
|
||||
pCrvRectEBorder->Close() ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrRectEnd( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrRectEnd) ||
|
||||
! pSfrRectEnd->AddExtLoop( Release( pCrvRectEBorder)) ||
|
||||
! pSfrRectEnd->IsValid())
|
||||
return false ;
|
||||
if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectEnd->GetNormVersor()))
|
||||
pSfrRectEnd->Invert() ;
|
||||
|
||||
// 2) ***
|
||||
|
||||
// Rettangolo all'inizio
|
||||
Vector3d vtTanCS = vtTanS_ ;
|
||||
Vector3d vtTanCE = vtTanE_ ;
|
||||
PtrOwner<ICurveComposite> pCrvRect_TanCLS_Border( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvRect_TanCLS_Border))
|
||||
return false ;
|
||||
pCrvRect_TanCLS_Border->AddPoint( ptS) ;
|
||||
pCrvRect_TanCLS_Border->AddLine( ptS + ( 1.5 * dRad + 500 * EPS_SMALL) * vtTanCS) ;
|
||||
vtOut = vtTanCS ; vtOut.Rotate( Z_AX, - 90) ;
|
||||
pCrvRect_TanCLS_Border->AddLine( ptS + ( 1.5 * dRad + 500 * EPS_SMALL) * vtTanCS + ( dRad + 500 * EPS_SMALL) * vtOut) ;
|
||||
pCrvRect_TanCLS_Border->AddLine( ptS + ( dRad + 500 * EPS_SMALL) * vtOut) ;
|
||||
pCrvRect_TanCLS_Border->Close() ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrRectCLStart( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrRectCLStart) ||
|
||||
! pSfrRectCLStart->AddExtLoop( Release( pCrvRect_TanCLS_Border)) ||
|
||||
! pSfrRectCLStart->IsValid())
|
||||
return false ;
|
||||
if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectCLStart->GetNormVersor()))
|
||||
pSfrRectCLStart->Invert() ;
|
||||
|
||||
// Rettangolo alla fine
|
||||
PtrOwner<ICurveComposite> pCrvRect_TanCLE_Border( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvRect_TanCLE_Border))
|
||||
return false ;
|
||||
pCrvRect_TanCLE_Border->AddPoint( ptE) ;
|
||||
pCrvRect_TanCLE_Border->AddLine( ptE + ( 1.5 * dRad + 500 * EPS_SMALL) * vtTanCE) ;
|
||||
vtOut = vtTanCE ; vtOut.Rotate( Z_AX, 90) ;
|
||||
pCrvRect_TanCLE_Border->AddLine( ptE + ( 1.5 * dRad + 500 * EPS_SMALL) * vtTanCE + ( dRad + 500 * EPS_SMALL) * vtOut) ;
|
||||
pCrvRect_TanCLE_Border->AddLine( ptE + ( dRad + 500 * EPS_SMALL) * vtOut) ;
|
||||
pCrvRect_TanCLE_Border->Close() ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrRectCLEEnd( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrRectCLEEnd) ||
|
||||
! pSfrRectCLEEnd->AddExtLoop( Release( pCrvRect_TanCLE_Border)) ||
|
||||
! pSfrRectCLEEnd->IsValid())
|
||||
return false ;
|
||||
if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectCLStart->GetNormVersor()))
|
||||
pSfrRectCLStart->Invert() ;
|
||||
|
||||
// alla superficie di incidenza, sottraggo i due rettangoli ricavati
|
||||
if ( ! pSfrInc->Subtract( *pSfrRectStart) ||
|
||||
! pSfrInc->Subtract( *pSfrRectEnd))
|
||||
return false ;
|
||||
|
||||
// tolgo ora i rettangoli per le tangenze ai chiusi
|
||||
pSfrInc->Subtract( *pSfrRectCLStart) ;
|
||||
pSfrInc->Subtract( *pSfrRectCLEEnd) ;
|
||||
|
||||
return pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0 ;
|
||||
return ( pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1109,11 +1007,30 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
// inverto se necessario
|
||||
if ( AreOppositeVectorApprox( pSfrBean->GetNormVersor(), pSfrInc->GetNormVersor()))
|
||||
pSfrBean->Invert() ;
|
||||
|
||||
// 7) se la "Regione a fagiolo" non influenza la regione di incidenza, la transcuro
|
||||
bool bDiscard = ! bIsIsland ; // non trascuro se si tratta di un'isola aperta
|
||||
for ( int cI = 0 ; cI < pSfrInc->GetChunkCount() && bDiscard ; ++ cI)
|
||||
for ( int cB = 0 ; cB < pSfrBean->GetChunkCount() && bDiscard ; ++ cB)
|
||||
bDiscard = ( pSfrInc->GetChunkSimpleClassification( cI, *pSfrBean, cB) != REGC_INTERS) ;
|
||||
bool bDiscard = false ;
|
||||
if ( ! bIsIsland) { // se tratto un loop esterno
|
||||
for ( int cI = 0 ; cI < pSfrInc->GetChunkCount() && ! bDiscard ; ++ cI)
|
||||
for ( int cB = 0 ; cB < pSfrBean->GetChunkCount() && ! bDiscard ; ++ cB)
|
||||
bDiscard = ( pSfrInc->GetChunkSimpleClassification( cI, *pSfrBean, cB) != REGC_INTERS) ;
|
||||
}
|
||||
else if ( bIsAllOpen && bIsIsland) { // se isola aperta
|
||||
for ( int cI = 0 ; cI < pSfrInc->GetChunkCount() && ! bDiscard ; ++ cI) {
|
||||
for ( int cB = 0 ; cB < pSfrBean->GetChunkCount() && ! bDiscard ; ++ cB) {
|
||||
if ( pSfrInc->GetChunkSimpleClassification( cI, *pSfrBean, cB) == REGC_IN1) {
|
||||
for ( int l = 1 ; l < pSfrBean->GetLoopCount( cB) ; ++ l) {
|
||||
PtrOwner<ISurfFlatRegion> pSfrTmp( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrTmp) || ! pSfrTmp->AddExtLoop( pSfrBean->GetLoop( cB, l)) ||
|
||||
! pSfrTmp->Invert())
|
||||
return false ;
|
||||
|
||||
bDiscard = ( pSfrInc->GetChunkSimpleClassification( cI, *pSfrTmp, 0) == REGC_IN1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! bDiscard) {
|
||||
// 8) aggiorno la regione di incidenza
|
||||
if ( ! pSfrInc->Add( *pSfrBean))
|
||||
@@ -1121,6 +1038,28 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
}
|
||||
pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ; // passo al tratto offsettato successivo
|
||||
}
|
||||
// 9) creo la regione squadrata da rimuovere alla regione di incidenza
|
||||
OffsetCurve OffsCrvRect ;
|
||||
if ( ! OffsCrvRect.Make( vpCrvs[cl], dDiamJ * 0.5, ICurve::OFF_FILLET))
|
||||
return false ;
|
||||
// 10) scorro tutte le curve di Offset che si sono formate, prendendo sempre la più lunga tra le rimanenti
|
||||
PtrOwner<ICurve> pOffLongestCrvRect( OffsCrvRect.GetLongerCurve()) ;
|
||||
while ( ! IsNull( pOffLongestCrvRect)) {
|
||||
|
||||
// 11) creo la regione di incidenza di tale curva ( "Curva a rettangolo")
|
||||
PtrOwner<ISurfFlatRegion> pSfrRect( GetSurfFlatRegionFromFatCurve( Release( pOffLongestCrvRect), dDiamJ * 0.5, true, false)) ;
|
||||
if ( IsNull( pSfrRect) || ! pSfrRect->IsValid())
|
||||
return false ;
|
||||
// inverto se necessario
|
||||
if ( AreOppositeVectorApprox( pSfrRect->GetNormVersor(), pSfrInc->GetNormVersor()))
|
||||
pSfrRect->Invert() ;
|
||||
|
||||
// 12) aggiorno la regione di incidenza
|
||||
if ( ! pSfrInc->Subtract( *pSfrRect))
|
||||
return false ;
|
||||
|
||||
pOffLongestCrvRect.Set( OffsCrvRect.GetLongerCurve()) ; // passo al tratto offsettato successivo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1129,12 +1068,17 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
// lato aperto al di fuori del volume di svuotatura... Devo controllare di non rovinare delle zone al di fuori di
|
||||
// esso !
|
||||
if ( PockParams.SfrLimit.IsValid()) {
|
||||
pSfrInc->Offset( 50 * EPS_SMALL, ICurve::OFF_FILLET) ;
|
||||
if ( ! pSfrInc->Subtract( PockParams.SfrLimit))
|
||||
// recupero la superficie limite
|
||||
PtrOwner<ISurfFlatRegion> pSfrLimit( GetSurfFlatRegion( PockParams.SfrLimit.Clone())) ;
|
||||
if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid())
|
||||
return false ;
|
||||
// piccolo Offset per sicurezza
|
||||
pSfrLimit->Offset( 50 * EPS_SMALL, ICurve::OFF_FILLET) ;
|
||||
pSfrInc->Subtract( *pSfrLimit) ; // rimuovo la regione limite
|
||||
|
||||
// può capitare che la regione Limite mi crei più Chunk sulla pSfrInc
|
||||
// I chunk da togliere sono tutti quelli che si sono separati dalla pCrvBorder
|
||||
// NB. Il mio obiettivo è quello di avere un'unica curva con estremi i due tratti aperti estremanti
|
||||
// NB. Il mio obiettivo è quello di avere un'unica curva con estremi i due tratti chiusi estremanti
|
||||
if ( pSfrInc->GetChunkCount() > 1) { // se ottengo più chunks
|
||||
PtrOwner<ISurfFlatRegion> pNewSfrInc( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pNewSfrInc))
|
||||
@@ -1178,13 +1122,29 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
if ( bIsAllOpen) {
|
||||
// pulisco la curva originale
|
||||
pCrvBorder->Clear() ;
|
||||
if ( bIsIsland) { // se isola inserisco il loop interno della regione
|
||||
pCrvNewBorder.Set( ConvertCurveToComposite( pSfrInc->GetLoop( 0, 1))) ;
|
||||
if ( IsNull( pCrvNewBorder) || ! pCrvNewBorder->IsValid())
|
||||
return false ;
|
||||
// imposto la curva come tutta aperta ( gira come girava già l'isola)
|
||||
for ( int u = 0 ; u < pCrvNewBorder->GetCurveCount() ; ++ u)
|
||||
pCrvNewBorder->SetCurveTempProp( u, 1, 0) ;
|
||||
if ( bIsIsland) { // se isola inserisco il loop interno corretto della regione
|
||||
for ( int l = 1 ; l < pSfrInc->GetLoopCount( 0) ; ++ l) {
|
||||
// recupero il Loop
|
||||
PtrOwner<ICurveComposite> pCrvIntLoop( ConvertCurveToComposite( pSfrInc->GetLoop( 0, l))) ;
|
||||
if ( IsNull( pCrvIntLoop) || ! pCrvIntLoop->IsValid())
|
||||
return false ;
|
||||
// controllo che sia interno alla curva di bordo corrente ( l'isola aperta)
|
||||
IntersCurveCurve ICC( *pCrvIntLoop, *pCrvCompo) ;
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ICC.GetCurveClassification( 0, EPS_SMALL, ccClass) &&
|
||||
int( ccClass.size()) == 1 &&
|
||||
ccClass[0].nClass == CRVC_OUT) {
|
||||
// il loop interno corretto va impostato come unico e nuovo loop interno della regione
|
||||
pCrvNewBorder->CopyFrom( pCrvIntLoop) ;
|
||||
if ( IsNull( pCrvNewBorder) || ! pCrvNewBorder->IsValid())
|
||||
return false ;
|
||||
// imposto la curva come tutta aperta ( gira come girava già l'isola)
|
||||
for ( int u = 0 ; u < pCrvNewBorder->GetCurveCount() ; ++ u)
|
||||
pCrvNewBorder->SetCurveTempProp( u, 1, 0) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// se bordo esterno inserisco il bordo esterno
|
||||
return pCrvBorder->AddCurve( Release( pCrvNewBorder)) ;
|
||||
@@ -6563,8 +6523,8 @@ AddOneWay( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double dStep, double dAngle, int nType, bool bSmooth,
|
||||
ICRVCOMPOPOVECTOR& vCrvCompoRes)
|
||||
CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double dStep, double dAngle,
|
||||
int nType, bool bSmooth, ISurfFlatRegion* pSfrLimit, ICRVCOMPOPOVECTOR& vCrvCompoRes)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid() ||
|
||||
@@ -6583,20 +6543,30 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
|
||||
myParams.bSmooth = bSmooth ;
|
||||
myParams.dAngle = dAngle ;
|
||||
myParams.dSideStep = dStep ;
|
||||
if ( pSfrLimit != nullptr && pSfrLimit->IsValid())
|
||||
myParams.SfrLimit.CopyFrom( pSfrLimit) ;
|
||||
|
||||
// ------------ gestione dei lati aperti -------------------
|
||||
// modifico la supericie in base alle proprietà di lato aperto/chiuso
|
||||
// creo un sistema di riferimento locale
|
||||
Point3d ptCenter ; pSfr->GetCentroid( ptCenter) ;
|
||||
Vector3d vtN = pSfr->GetNormVersor() ;
|
||||
Frame3d frLoc ;
|
||||
if ( ! frLoc.Set( ptCenter, vtN))
|
||||
return false ;
|
||||
// porto la superficie da svuotare in tale sistema
|
||||
PtrOwner<ISurfFlatRegion> pSfrAdj( CloneSurfFlatRegion( pSfr)) ;
|
||||
if ( IsNull( pSfrAdj) ||
|
||||
! pSfrAdj->ToLoc( frLoc) ||
|
||||
! ModifySurfByOpenEdges( pSfrAdj, myParams) ||
|
||||
! pSfrAdj->ToGlob( frLoc))
|
||||
if ( IsNull( pSfrAdj) || ! pSfrAdj->ToLoc( frLoc))
|
||||
return false ;
|
||||
// porto la superficie limite ( se valida) in tale sistema
|
||||
if ( myParams.SfrLimit.IsValid())
|
||||
myParams.SfrLimit.ToLoc( frLoc) ;
|
||||
// modifico la superficie da svuotare estendendo i lati aperti
|
||||
if ( ! ModifySurfByOpenEdges( pSfrAdj, myParams))
|
||||
return false ;
|
||||
// riporto tutto nel frame originale
|
||||
pSfrAdj->ToGlob( frLoc) ;
|
||||
if ( myParams.SfrLimit.IsValid())
|
||||
myParams.SfrLimit.ToGlob( frLoc) ;
|
||||
|
||||
// ------------ calcolo delle curve elementari della superficie -------------------
|
||||
switch ( nType) {
|
||||
|
||||
Reference in New Issue
Block a user