EgtMachKernel :
- In finiture aggiunte considerazioni per invesione utensile, migliorate e corrette finiture Optimal - in PocketingNT aggiunta gestione di isole aperte all'interno del grezzo.
This commit is contained in:
+220
-208
@@ -3113,8 +3113,7 @@ PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm)
|
||||
* come chiusi */
|
||||
|
||||
// controllo dei parametri
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid() ||
|
||||
pStm == nullptr)
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid() || pStm == nullptr)
|
||||
return false ;
|
||||
if ( ! pStm->IsValid())
|
||||
return true ;
|
||||
@@ -3125,7 +3124,7 @@ PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm)
|
||||
|
||||
// recupero i Chunk della superficie
|
||||
ISURFFRPOVECTOR vChunks( pSfr->GetChunkCount()) ;
|
||||
for ( int nC = 0 ; nC < int( vChunks.size()) ; ++ nC)
|
||||
for ( int nC = 0 ; nC < ssize( vChunks) ; ++ nC)
|
||||
vChunks[nC].Set( pSfr->CloneChunk( nC)) ;
|
||||
|
||||
// definisco un frame locale nel piano XY
|
||||
@@ -3140,10 +3139,9 @@ PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm)
|
||||
if ( GetValInNotes( m_Params.m_sUserNotes, UN_OPEN, dOpenExtension) && dOpenExtension > EPS_SMALL)
|
||||
m_dOpenInRawExtension = dOpenExtension ;
|
||||
|
||||
// se la superficie ha flag di OpenOutRaw e non è stata impostata alcuna estensione massima,
|
||||
// non modifico la geometria, lascio l'aperto esattamente dove si trova
|
||||
// se invece ho flat di OpenOutRaw, dato che il lato aperto viene lasciato tale, devo ridurre la
|
||||
// sua estensione del raggio utensile
|
||||
// se la superficie ha flag di OpenOutRaw e non è stata impostata alcuna estensione massima, non modifico la geometria,
|
||||
// lascio l'aperto esattamente dove si trova, se invece ho il flag di OpenOutRaw, dato che il lato aperto viene lasciato tale,
|
||||
// devo ridurre la sua estensione del raggio utensile
|
||||
if ( m_bOpenOutRaw) {
|
||||
if ( dOpenExtension < 10. * EPS_SMALL)
|
||||
return true ;
|
||||
@@ -3171,223 +3169,237 @@ PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm)
|
||||
m_pGeomDB->SetMaterial( _a, Color( .35, .65, .45, .35)) ;
|
||||
#endif
|
||||
|
||||
// recupero solo la curva di bordo esterno, le isole aperte per ora sono trascurate
|
||||
// scorro i Chunk della regione piana da lavorare
|
||||
bool bModifSfr = false ;
|
||||
for ( int nC = 0 ; nC < int( vChunks.size()) ; ++ nC) {
|
||||
// recupero la curva di bordo
|
||||
PtrOwner<ICurveComposite> pCrvBorder( ConvertCurveToComposite( vChunks[nC]->GetLoop( 0, 0))) ;
|
||||
if ( IsNull( pCrvBorder) || ! pCrvBorder->IsValid())
|
||||
return false ;
|
||||
// recupero i tratti omogenei
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
GetHomogeneousParts( pCrvBorder, vpCrvs) ;
|
||||
// se tutta chiusa, non faccio nulla
|
||||
if ( int( vpCrvs.size()) == 1 && vpCrvs[0]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE)
|
||||
continue ;
|
||||
// scorro i tratti alla ricerca di lati aperti ( esistono necessariamente)
|
||||
bool bOpenCrvInPart = false ;
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) {
|
||||
// analizzo le sottocurve del tratto
|
||||
for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j) {
|
||||
// per ogni sottocurva considero punto iniziale, finale e medio per campionarla
|
||||
// ( si potrebbe in futuro campionare in maniera più fitta )
|
||||
PNTVECTOR vPt( 3, P_INVALID) ;
|
||||
vpCrvs[i]->GetCurve( j)->GetStartPoint( vPt[0]) ;
|
||||
vpCrvs[i]->GetCurve( j)->GetMidPoint( vPt[1]) ;
|
||||
vpCrvs[i]->GetCurve( j)->GetEndPoint( vPt[2]) ;
|
||||
// classifico tali punti rispetto alla superficie
|
||||
bool bOpenEdgeInStm = false ;
|
||||
double dDist = 0. ;
|
||||
for ( int nPt = 0 ; nPt < int( vPt.size()) && ! bOpenEdgeInStm ; ++ nPt) {
|
||||
DistPointSurfTm DistPtStm( vPt[nPt], *pStm) ;
|
||||
bOpenEdgeInStm = ( DistPtStm.IsPointInside() &&
|
||||
DistPtStm.GetDist( dDist) &&
|
||||
dDist > TOL_PT_INSIDE_STM) ;
|
||||
}
|
||||
// se curva aperta nel pezzo, la classifico
|
||||
if ( bOpenEdgeInStm) {
|
||||
vpCrvs[i]->SetCurveTempProp( j, TEMP_PROP_OPEN_EDGE_IN_RAW, 0) ;
|
||||
bOpenCrvInPart = true ;
|
||||
for ( int nC = 0 ; nC < ssize( vChunks) ; ++ nC) {
|
||||
// definisco le nuove curve di bordo
|
||||
bool bModifChunk = false ;
|
||||
int nLoops = vChunks[nC]->GetLoopCount( 0) ;
|
||||
ICRVCOMPOPOVECTOR vCrvNewBorder ; vCrvNewBorder.resize( nLoops) ;
|
||||
for ( int nL = 0 ; nL < nLoops ; ++ nL) {
|
||||
// recupero la curva di bordo
|
||||
PtrOwner<ICurveComposite> pCrvBorder( ConvertCurveToComposite( vChunks[nC]->GetLoop( 0, nL))) ;
|
||||
if ( IsNull( pCrvBorder) || ! pCrvBorder->IsValid())
|
||||
return false ;
|
||||
// recupero i tratti omogenei
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
GetHomogeneousParts( pCrvBorder, vpCrvs) ;
|
||||
// se tutta chiusa, non faccio nulla
|
||||
if ( ssize( vpCrvs) == 1 && vpCrvs[0]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE)
|
||||
continue ;
|
||||
// scorro i tratti alla ricerca di lati aperti ( esistono necessariamente)
|
||||
bool bOpenCrvInPart = false ;
|
||||
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) {
|
||||
if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) {
|
||||
// analizzo le sottocurve del tratto
|
||||
for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j) {
|
||||
// per ogni sottocurva considero punto iniziale, finale e medio per campionarla
|
||||
PNTVECTOR vPt( 3, P_INVALID) ;
|
||||
vpCrvs[i]->GetCurve( j)->GetStartPoint( vPt[0]) ;
|
||||
vpCrvs[i]->GetCurve( j)->GetMidPoint( vPt[1]) ;
|
||||
vpCrvs[i]->GetCurve( j)->GetEndPoint( vPt[2]) ;
|
||||
// classifico tali punti rispetto alla superficie
|
||||
bool bOpenEdgeInStm = false ;
|
||||
double dDist = 0. ;
|
||||
for ( int nPt = 0 ; nPt < int( vPt.size()) && ! bOpenEdgeInStm ; ++ nPt) {
|
||||
DistPointSurfTm DistPtStm( vPt[nPt], *pStm) ;
|
||||
bOpenEdgeInStm = ( DistPtStm.IsPointInside() &&
|
||||
DistPtStm.GetDist( dDist) &&
|
||||
dDist > TOL_PT_INSIDE_STM) ;
|
||||
}
|
||||
// se curva aperta nel pezzo, la classifico
|
||||
if ( bOpenEdgeInStm) {
|
||||
vpCrvs[i]->SetCurveTempProp( j, TEMP_PROP_OPEN_EDGE_IN_RAW, 0) ;
|
||||
bOpenCrvInPart = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se non sono state trovate curve interne al pezzo, allora passo al bordo successivo
|
||||
if ( ! bOpenCrvInPart)
|
||||
continue ;
|
||||
// ricostruisco il bordo mediante proprietà assegnate ( esistono lati aperti interni al pezzo)
|
||||
PtrOwner<ICurveComposite> pCrvNewBorder( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvNewBorder))
|
||||
return false ;
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
if ( ! pCrvNewBorder->AddCurve( Release( vpCrvs[i])))
|
||||
// se non sono state trovate curve interne al pezzo, allora passo al bordo successivo
|
||||
if ( ! bOpenCrvInPart)
|
||||
continue ;
|
||||
// ricostruisco il bordo mediante proprietà assegnate ( esistono lati aperti interni al pezzo)
|
||||
PtrOwner<ICurveComposite> pCrvNewBorder( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvNewBorder))
|
||||
return false ;
|
||||
}
|
||||
// recupero i nuovi tratti omogenei
|
||||
GetHomogeneousParts( pCrvNewBorder, vpCrvs) ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
DebugDrawOpenEdgesInRaw( vpCrvs, nLayBase) ;
|
||||
#endif
|
||||
// caso limite : tutta la curva è aperta ed interna alla regione
|
||||
if ( int( vpCrvs.size()) == 1 && vpCrvs[0]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE_IN_RAW) {
|
||||
// Offset del bordo del Chunk
|
||||
OffsetCurve OffsCrv ;
|
||||
OffsCrv.Make( pCrvNewBorder, m_dOpenInRawExtension, ICurve::OFF_FILLET) ;
|
||||
pCrvNewBorder.Set( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ;
|
||||
if ( IsNull( pCrvNewBorder) || ! pCrvNewBorder->IsValid())
|
||||
return false ;
|
||||
// considero il bordo come tutto chiuso ( evito entrate da fuori dal pezzo)
|
||||
for ( int i = 0 ; i < pCrvNewBorder->GetCurveCount() ; ++ i)
|
||||
pCrvNewBorder->SetCurveTempProp( i, m_bOpenOutRaw ? TEMP_PROP_OPEN_EDGE : TEMP_PROP_CLOSE_EDGE, 0) ;
|
||||
}
|
||||
// se invece presenta solo alcuni tratti Open interni al pezzo
|
||||
else {
|
||||
// porto tutti i tratti ricavati nel piano XY per le intersezioni
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i)
|
||||
vpCrvs[i]->ToLoc( frXY) ;
|
||||
// scorro i tratti con proprietà uniformi
|
||||
bool bOk = true ;
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
if ( ! bOk) {
|
||||
// considero il tratto precedente come chiuso
|
||||
for ( int j = 0 ; j < vpCrvs[i-1]->GetCurveCount() ; ++ j)
|
||||
vpCrvs[i-1]->SetCurveTempProp( j, TEMP_PROP_CLOSE_EDGE, 0) ;
|
||||
bOk = true ;
|
||||
}
|
||||
// se tratto Open interno al grezzo
|
||||
if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE_IN_RAW) {
|
||||
// effettuo Offset del tratto in esame
|
||||
OffsetCurve OffsCrv ;
|
||||
OffsCrv.Make( vpCrvs[i], m_dOpenInRawExtension, ICurve::OFF_FILLET) ;
|
||||
PtrOwner<ICurveComposite> pCrvOffsOpenInPart( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ;
|
||||
if ( IsNull( pCrvOffsOpenInPart) || ! pCrvOffsOpenInPart->IsValid()) {
|
||||
bOk = false ;
|
||||
continue ;
|
||||
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) {
|
||||
if ( ! pCrvNewBorder->AddCurve( Release( vpCrvs[i])))
|
||||
return false ;
|
||||
}
|
||||
// recupero i nuovi tratti omogenei
|
||||
GetHomogeneousParts( pCrvNewBorder, vpCrvs) ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
DebugDrawOpenEdgesInRaw( vpCrvs, nLayBase) ;
|
||||
#endif
|
||||
// caso limite : tutta la curva è aperta ed interna alla regione
|
||||
if ( ssize( vpCrvs) == 1 && vpCrvs[0]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE_IN_RAW) {
|
||||
// Offset del bordo del Chunk
|
||||
OffsetCurve OffsCrv ;
|
||||
OffsCrv.Make( pCrvNewBorder, m_dOpenInRawExtension, ICurve::OFF_FILLET) ;
|
||||
pCrvNewBorder.Set( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ;
|
||||
if ( IsNull( pCrvNewBorder) || ! pCrvNewBorder->IsValid())
|
||||
return false ;
|
||||
// considero il bordo come tutto chiuso ( evito entrate da fuori dal pezzo)
|
||||
for ( int i = 0 ; i < pCrvNewBorder->GetCurveCount() ; ++ i)
|
||||
pCrvNewBorder->SetCurveTempProp( i, m_bOpenOutRaw ? TEMP_PROP_OPEN_EDGE : TEMP_PROP_CLOSE_EDGE, 0) ;
|
||||
}
|
||||
// se invece presenta solo alcuni tratti Open interni al pezzo
|
||||
else {
|
||||
// porto tutti i tratti ricavati nel piano XY per le intersezioni
|
||||
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i)
|
||||
vpCrvs[i]->ToLoc( frXY) ;
|
||||
// scorro i tratti con proprietà uniformi
|
||||
bool bOk = true ;
|
||||
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) {
|
||||
if ( ! bOk) {
|
||||
// considero il tratto precedente come chiuso
|
||||
for ( int j = 0 ; j < vpCrvs[i-1]->GetCurveCount() ; ++ j)
|
||||
vpCrvs[i-1]->SetCurveTempProp( j, TEMP_PROP_CLOSE_EDGE, 0) ;
|
||||
bOk = true ;
|
||||
}
|
||||
// recupero tratto precedente e successivo
|
||||
int nIndPrev = ( i > 0 ? i - 1 : int( vpCrvs.size()) - 1) ;
|
||||
int nIndAfter = ( i < int( vpCrvs.size()) - 1 ? i + 1 : 0) ;
|
||||
// estendo per sicurezza il tratto di Offset ( per angoli acuti con i tratti adiacenti)
|
||||
pCrvOffsOpenInPart->ExtendStartByLen( LEN_EXTENSION) ;
|
||||
pCrvOffsOpenInPart->ExtendEndByLen( LEN_EXTENSION) ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayConstr, pCrvOffsOpenInPart->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, ORANGE) ;
|
||||
#endif
|
||||
// definisco due segmenti lineari
|
||||
PtrOwner<ICurveLine> pLinePrev( CreateCurveLine()) ;
|
||||
PtrOwner<ICurveLine> pLineAfter( CreateCurveLine()) ;
|
||||
if ( IsNull( pLinePrev) || IsNull( pLineAfter))
|
||||
return false ;
|
||||
Point3d ptLineStart ;
|
||||
Vector3d vtLineStart ;
|
||||
vpCrvs[nIndPrev]->GetEndPoint( ptLineStart) ;
|
||||
vpCrvs[nIndPrev]->GetEndDir( vtLineStart) ;
|
||||
if ( ! pLinePrev->Set( ptLineStart, ptLineStart + LEN_EXTENSION * vtLineStart))
|
||||
return false ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
_a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayConstr, pLinePrev->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, BLACK) ;
|
||||
#endif
|
||||
Point3d ptLineEnd ;
|
||||
Vector3d vtLineEnd ;
|
||||
vpCrvs[nIndAfter]->GetStartPoint( ptLineEnd) ;
|
||||
vpCrvs[nIndAfter]->GetStartDir( vtLineEnd) ;
|
||||
if ( ! pLineAfter->Set( ptLineEnd - LEN_EXTENSION * vtLineEnd, ptLineEnd))
|
||||
return false ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
_a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayConstr, pLineAfter->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, BLACK) ;
|
||||
#endif
|
||||
// intersezione con primo segmento ( raccordo verso lato Open In Raw Offs)
|
||||
Point3d ptIntS ;
|
||||
double dUS_Trim_Line ;
|
||||
double dUS_Trim_Offs ;
|
||||
IntersCurveCurve ICC_Prev( *pLinePrev, *pCrvOffsOpenInPart) ;
|
||||
if ( ICC_Prev.GetIntersCount() > 0 && ICC_Prev.GetIntersPointNearTo( 0, ptLineStart, ptIntS)) {
|
||||
pLinePrev->GetParamAtPoint( ptIntS, dUS_Trim_Line) ;
|
||||
pCrvOffsOpenInPart->GetParamAtPoint( ptIntS, dUS_Trim_Offs) ;
|
||||
}
|
||||
else {
|
||||
bOk = false ;
|
||||
continue ;
|
||||
}
|
||||
// intersezione con secondo segmento ( raccordo da Lato Open In Raw Offs)
|
||||
Point3d ptIntE ;
|
||||
double dUE_Trim_Line ;
|
||||
double dUE_Trim_Offs ;
|
||||
IntersCurveCurve ICC_After( *pLineAfter, *pCrvOffsOpenInPart) ;
|
||||
if ( ICC_After.GetIntersCount() > 0 && ICC_After.GetIntersPointNearTo( 0, ptLineEnd, ptIntE)) {
|
||||
pLineAfter->GetParamAtPoint( ptIntE, dUE_Trim_Line) ;
|
||||
pCrvOffsOpenInPart->GetParamAtPoint( ptIntE, dUE_Trim_Offs) ;
|
||||
}
|
||||
else {
|
||||
bOk = false ;
|
||||
continue ;
|
||||
}
|
||||
// se le rette si intersecano tra loro prima di raccordarsi sull'Offset
|
||||
if ( dUS_Trim_Offs > dUE_Trim_Offs) {
|
||||
// recupero punto di intersezione tra le rette
|
||||
IntersCurveCurve ILL( *pLinePrev, *pLineAfter) ;
|
||||
Point3d ptIntersLL ;
|
||||
if ( ILL.GetIntersCount() != 1 ||
|
||||
! ILL.GetIntersPointNearTo( 0, ptLineStart, ptIntersLL) ||
|
||||
! pLinePrev->GetParamAtPoint( ptIntersLL, dUS_Trim_Line) ||
|
||||
! pLineAfter->GetParamAtPoint( ptIntersLL, dUE_Trim_Line)) {
|
||||
// se tratto Open interno al grezzo
|
||||
if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE_IN_RAW) {
|
||||
// effettuo Offset del tratto in esame
|
||||
OffsetCurve OffsCrv ;
|
||||
OffsCrv.Make( vpCrvs[i], m_dOpenInRawExtension, ICurve::OFF_FILLET) ;
|
||||
PtrOwner<ICurveComposite> pCrvOffsOpenInPart( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ;
|
||||
if ( IsNull( pCrvOffsOpenInPart) || ! pCrvOffsOpenInPart->IsValid()) {
|
||||
bOk = false ;
|
||||
continue ;
|
||||
}
|
||||
// pulisco la curva di Offset
|
||||
pCrvOffsOpenInPart->Clear() ;
|
||||
// recupero tratto precedente e successivo
|
||||
int nIndPrev = ( i > 0 ? i - 1 : ssize( vpCrvs) - 1) ;
|
||||
int nIndAfter = ( i < ssize( vpCrvs) - 1 ? i + 1 : 0) ;
|
||||
// estendo per sicurezza il tratto di Offset ( per angoli acuti con i tratti adiacenti)
|
||||
pCrvOffsOpenInPart->ExtendStartByLen( LEN_EXTENSION) ;
|
||||
pCrvOffsOpenInPart->ExtendEndByLen( LEN_EXTENSION) ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayConstr, pCrvOffsOpenInPart->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, ORANGE) ;
|
||||
#endif
|
||||
// definisco due segmenti lineari
|
||||
PtrOwner<ICurveLine> pLinePrev( CreateCurveLine()) ;
|
||||
PtrOwner<ICurveLine> pLineAfter( CreateCurveLine()) ;
|
||||
if ( IsNull( pLinePrev) || IsNull( pLineAfter))
|
||||
return false ;
|
||||
Point3d ptLineStart ;
|
||||
Vector3d vtLineStart ;
|
||||
vpCrvs[nIndPrev]->GetEndPoint( ptLineStart) ;
|
||||
vpCrvs[nIndPrev]->GetEndDir( vtLineStart) ;
|
||||
if ( ! pLinePrev->Set( ptLineStart, ptLineStart + LEN_EXTENSION * vtLineStart))
|
||||
return false ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
_a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayConstr, pLinePrev->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, BLACK) ;
|
||||
#endif
|
||||
Point3d ptLineEnd ;
|
||||
Vector3d vtLineEnd ;
|
||||
vpCrvs[nIndAfter]->GetStartPoint( ptLineEnd) ;
|
||||
vpCrvs[nIndAfter]->GetStartDir( vtLineEnd) ;
|
||||
if ( ! pLineAfter->Set( ptLineEnd - LEN_EXTENSION * vtLineEnd, ptLineEnd))
|
||||
return false ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
_a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayConstr, pLineAfter->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, BLACK) ;
|
||||
#endif
|
||||
// intersezione con primo segmento ( raccordo verso lato Open In Raw Offs)
|
||||
Point3d ptIntS ;
|
||||
double dUS_Trim_Line ;
|
||||
double dUS_Trim_Offs ;
|
||||
IntersCurveCurve ICC_Prev( *pLinePrev, *pCrvOffsOpenInPart) ;
|
||||
if ( ICC_Prev.GetIntersCount() > 0 && ICC_Prev.GetIntersPointNearTo( 0, ptLineStart, ptIntS)) {
|
||||
pLinePrev->GetParamAtPoint( ptIntS, dUS_Trim_Line) ;
|
||||
pCrvOffsOpenInPart->GetParamAtPoint( ptIntS, dUS_Trim_Offs) ;
|
||||
}
|
||||
else {
|
||||
bOk = false ;
|
||||
continue ;
|
||||
}
|
||||
// intersezione con secondo segmento ( raccordo da Lato Open In Raw Offs)
|
||||
Point3d ptIntE ;
|
||||
double dUE_Trim_Line ;
|
||||
double dUE_Trim_Offs ;
|
||||
IntersCurveCurve ICC_After( *pLineAfter, *pCrvOffsOpenInPart) ;
|
||||
if ( ICC_After.GetIntersCount() > 0 && ICC_After.GetIntersPointNearTo( 0, ptLineEnd, ptIntE)) {
|
||||
pLineAfter->GetParamAtPoint( ptIntE, dUE_Trim_Line) ;
|
||||
pCrvOffsOpenInPart->GetParamAtPoint( ptIntE, dUE_Trim_Offs) ;
|
||||
}
|
||||
else {
|
||||
bOk = false ;
|
||||
continue ;
|
||||
}
|
||||
// se le rette si intersecano tra loro prima di raccordarsi sull'Offset
|
||||
if ( dUS_Trim_Offs > dUE_Trim_Offs) {
|
||||
// recupero punto di intersezione tra le rette
|
||||
IntersCurveCurve ILL( *pLinePrev, *pLineAfter) ;
|
||||
Point3d ptIntersLL ;
|
||||
if ( ILL.GetIntersCount() != 1 ||
|
||||
! ILL.GetIntersPointNearTo( 0, ptLineStart, ptIntersLL) ||
|
||||
! pLinePrev->GetParamAtPoint( ptIntersLL, dUS_Trim_Line) ||
|
||||
! pLineAfter->GetParamAtPoint( ptIntersLL, dUE_Trim_Line)) {
|
||||
bOk = false ;
|
||||
continue ;
|
||||
}
|
||||
// pulisco la curva di Offset
|
||||
pCrvOffsOpenInPart->Clear() ;
|
||||
}
|
||||
// se le rette non si intersecano tra loro
|
||||
else {
|
||||
double dU_Offs_Trim_Start = 0. ;
|
||||
pCrvOffsOpenInPart->GetParamAtPoint( ptIntS, dU_Offs_Trim_Start) ;
|
||||
pCrvOffsOpenInPart->TrimStartAtParam( dU_Offs_Trim_Start) ;
|
||||
double dU_Offs_Trim_End = 0. ;
|
||||
pCrvOffsOpenInPart->GetParamAtPoint( ptIntE, dU_Offs_Trim_End) ;
|
||||
pCrvOffsOpenInPart->TrimEndAtParam( dU_Offs_Trim_End) ;
|
||||
}
|
||||
// aggiorno tutte le curve e le loro proprietà
|
||||
pLinePrev->TrimEndAtParam( dUS_Trim_Line) ;
|
||||
pLinePrev->SetTempProp( vpCrvs[nIndPrev]->GetTempProp( 0), 0) ;
|
||||
vpCrvs[nIndPrev]->AddCurve( Release( pLinePrev), true) ;
|
||||
pLineAfter->TrimStartAtParam( dUE_Trim_Line) ;
|
||||
pLineAfter->SetTempProp( vpCrvs[nIndAfter]->GetTempProp( 0), 0) ;
|
||||
vpCrvs[nIndAfter]->AddCurve( Release( pLineAfter), false) ;
|
||||
vpCrvs[i].Set( Release( pCrvOffsOpenInPart)) ;
|
||||
// assegno proprietà di lato aperto/chiuso
|
||||
for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j)
|
||||
vpCrvs[i]->SetCurveTempProp( j, m_bOpenOutRaw ? TEMP_PROP_OPEN_EDGE : TEMP_PROP_CLOSE_EDGE, 0) ;
|
||||
}
|
||||
// se le rette non si intersecano tra loro
|
||||
else {
|
||||
double dU_Offs_Trim_Start = 0. ;
|
||||
pCrvOffsOpenInPart->GetParamAtPoint( ptIntS, dU_Offs_Trim_Start) ;
|
||||
pCrvOffsOpenInPart->TrimStartAtParam( dU_Offs_Trim_Start) ;
|
||||
double dU_Offs_Trim_End = 0. ;
|
||||
pCrvOffsOpenInPart->GetParamAtPoint( ptIntE, dU_Offs_Trim_End) ;
|
||||
pCrvOffsOpenInPart->TrimEndAtParam( dU_Offs_Trim_End) ;
|
||||
}
|
||||
// aggiorno tutte le curve e le loro proprietà
|
||||
pLinePrev->TrimEndAtParam( dUS_Trim_Line) ;
|
||||
pLinePrev->SetTempProp( vpCrvs[nIndPrev]->GetTempProp( 0), 0) ;
|
||||
vpCrvs[nIndPrev]->AddCurve( Release( pLinePrev), true) ;
|
||||
pLineAfter->TrimStartAtParam( dUE_Trim_Line) ;
|
||||
pLineAfter->SetTempProp( vpCrvs[nIndAfter]->GetTempProp( 0), 0) ;
|
||||
vpCrvs[nIndAfter]->AddCurve( Release( pLineAfter), false) ;
|
||||
vpCrvs[i].Set( Release( pCrvOffsOpenInPart)) ;
|
||||
// assegno proprietà di lato aperto/chiuso
|
||||
for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j)
|
||||
vpCrvs[i]->SetCurveTempProp( j, m_bOpenOutRaw ? TEMP_PROP_OPEN_EDGE : TEMP_PROP_CLOSE_EDGE, 0) ;
|
||||
}
|
||||
// ricostrusico il nuovo bordo
|
||||
pCrvNewBorder->Clear() ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
DebugDrawOpenEdgesInRaw( vpCrvs, nLayResult) ;
|
||||
#endif
|
||||
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) {
|
||||
if ( ! IsNull( vpCrvs[i]) && vpCrvs[i]->IsValid() && vpCrvs[i]->GetCurveCount() > 0) {
|
||||
if ( ! pCrvNewBorder->AddCurve( Release( vpCrvs[i])))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// lo riporto nel frame globale
|
||||
pCrvNewBorder->ToGlob( frXY) ;
|
||||
}
|
||||
// ricostrusico il nuovo bordo
|
||||
pCrvNewBorder->Clear() ;
|
||||
#if DEBUG_OPEN_EDGE_IN_RAW
|
||||
DebugDrawOpenEdgesInRaw( vpCrvs, nLayResult) ;
|
||||
#endif
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
if ( ! IsNull( vpCrvs[i]) && vpCrvs[i]->IsValid() && vpCrvs[i]->GetCurveCount() > 0) {
|
||||
if ( ! pCrvNewBorder->AddCurve( Release( vpCrvs[i])))
|
||||
// aggiorno il vettore dei bordi e il Flag di modifica del Chunk corrente
|
||||
if ( ! vCrvNewBorder[nL].Set( Release( pCrvNewBorder)))
|
||||
return false ;
|
||||
bModifSfr = true ;
|
||||
bModifChunk = true ;
|
||||
}
|
||||
// se il chunk ha subito modifiche ricostruisco i suoi Loops
|
||||
if ( bModifChunk) {
|
||||
for ( int nL = 0 ; nL < nLoops ; ++ nL) {
|
||||
if ( IsNull( vCrvNewBorder[nL]) || ! vCrvNewBorder[nL]->IsValid()) {
|
||||
if ( ! vCrvNewBorder[nL].Set( ConvertCurveToComposite( vChunks[nC]->GetLoop( 0, nL))))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// lo riporto nel frame globale
|
||||
pCrvNewBorder->ToGlob( frXY) ;
|
||||
vChunks[nC]->Clear() ;
|
||||
for ( int nL = 0 ; nL < nLoops ; ++ nL) {
|
||||
if ( ( nL == 0 && ! vChunks[nC]->AddExtLoop( Release( vCrvNewBorder[nL]))) ||
|
||||
( nL > 0 && ! vChunks[nC]->AddIntLoop( Release( vCrvNewBorder[nL]))))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// ricostruisco il Chunk con il nuovo bordo
|
||||
PtrOwner<ISurfFlatRegion> pNewChunk( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pNewChunk) || ! pNewChunk->AddExtLoop( Release( pCrvNewBorder)))
|
||||
return false ;
|
||||
for ( int nI = 1 ; nI < vChunks[nC]->GetLoopCount( 0) ; ++ nI) {
|
||||
if ( ! pNewChunk->AddIntLoop( vChunks[nC]->GetLoop( 0, nI)))
|
||||
return false ;
|
||||
}
|
||||
vChunks[nC].Set( Release( pNewChunk)) ;
|
||||
bModifSfr = true ;
|
||||
}
|
||||
|
||||
// recupero la regione finale
|
||||
@@ -3395,7 +3407,7 @@ PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm)
|
||||
PtrOwner<ISurfFlatRegion> pSfrTmp( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrTmp))
|
||||
return false ;
|
||||
for ( auto& pSfrC : vChunks) {
|
||||
for ( PtrOwner<ISurfFlatRegion>& pSfrC : vChunks) {
|
||||
if ( pSfrTmp->IsValid())
|
||||
pSfrTmp->Add( *pSfrC) ;
|
||||
else
|
||||
|
||||
+437
-262
@@ -1997,9 +1997,11 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId)
|
||||
return true ;
|
||||
|
||||
// tengo una copia della regione attuale, nel caso di finitura Optimal
|
||||
PtrOwner<ISurfFlatRegion> pSfrCntOrig( CloneSurfFlatRegion( pSfrCnt)) ;
|
||||
if ( IsNull( pSfrCntOrig) || ! pSfrCntOrig->IsValid())
|
||||
return false ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrCntOrig( nullptr) ;
|
||||
if ( m_Params.m_nSubType == SURFFIN_SUB_OPTIMAL) {
|
||||
if ( ! pSfrCntOrig.Set( CloneSurfFlatRegion( pSfrCnt)) || ! pSfrCntOrig->IsValid())
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se richiesto, elimino le parti al massimo affondamento
|
||||
bool bSkipMaxDown = true ;
|
||||
@@ -2275,7 +2277,7 @@ SurfFinishing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons
|
||||
// calcolo lo ZigZag
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
if ( ! CalcPocketing( pSfrCnt, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5.,
|
||||
POCKET_ZIGZAG, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
|
||||
POCKET_ZIGZAG, false, false, m_Params.m_bInvert, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
|
||||
GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) {
|
||||
m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ;
|
||||
return false ;
|
||||
@@ -2303,7 +2305,7 @@ SurfFinishing::AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons
|
||||
// calcolo OneWay
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
if ( ! CalcPocketing( pSfrCnt, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5.,
|
||||
POCKET_ONEWAY, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
|
||||
POCKET_ONEWAY, false, false, m_Params.m_bInvert, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
|
||||
GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) {
|
||||
m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ;
|
||||
return false ;
|
||||
@@ -2331,7 +2333,7 @@ SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons
|
||||
int nType = ( bInVsOut ? POCKET_SPIRALIN : POCKET_SPIRALOUT) ;
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
if ( ! CalcPocketing( pSfrCnt, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5.,
|
||||
nType, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
|
||||
nType, false, false, m_Params.m_bInvert, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
|
||||
GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) {
|
||||
m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ;
|
||||
return false ;
|
||||
@@ -2933,7 +2935,7 @@ SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSu
|
||||
|
||||
// --- se ho una sola curva, allora controllo se posso cambiare il suo punto d'inizio
|
||||
// nel caso non sia la prima in assoluto [ -> controllo ptRef]
|
||||
if ( int( vIndependentCurveGroup[nPath].size()) == 1) {
|
||||
if ( ssize( vIndependentCurveGroup[nPath]) == 1) {
|
||||
if ( ptRef.IsValid()) {
|
||||
// --- se la curva di bordo singola è aperta
|
||||
if ( ! vIndependentCurveGroup[nPath][0]->IsClosed()) {
|
||||
@@ -3031,6 +3033,7 @@ SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSu
|
||||
PtrOwner<ICurve> pLineLinkProj( ProjectCurveOnPlane( *pLineLink, plProjection)) ;
|
||||
if ( IsNull( pLineLinkProj) || ! pLineLinkProj->IsValid())
|
||||
return false ;
|
||||
|
||||
// effettuo la classificazione
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! pSfrClass->GetCurveClassification( *pLineLinkProj, EPS_SMALL, ccClass))
|
||||
@@ -3082,7 +3085,7 @@ SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSu
|
||||
if ( ! vCompoLink[nCompo + 1]->IsValid())
|
||||
continue ; // il link rimane inizializzato e non valido ( 0 curve)
|
||||
|
||||
// porto il link sul piano della curva più in alto tra le due
|
||||
// porto il link sul piano della curva più in basso tra le due
|
||||
Point3d ptCheck ;
|
||||
vIndependentCurveGroup[nPath][nCompo + 1]->GetStartPoint( ptCheck) ;
|
||||
double dSfrDistNext = DistPointPlane( ptCheck, plProjection) ;
|
||||
@@ -3101,7 +3104,7 @@ SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSu
|
||||
int nLay = GDB_ID_NULL ;
|
||||
Color myCol = INVISIBLE ;
|
||||
#endif
|
||||
for ( int nCompo = 0 ; nCompo < ssize( vIndependentCurveGroup[nPath]) - 1 ; ++ nCompo) {
|
||||
for ( int nCompo = 0 ; nCompo < ssize( vIndependentCurveGroup[nPath]) ; ++ nCompo) {
|
||||
if ( IsNull( vCompoLink[nCompo]) || ! vCompoLink[nCompo]->IsValid()) {
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
|
||||
@@ -3134,10 +3137,8 @@ SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSu
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFinishing::CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frPocket,
|
||||
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth,
|
||||
const Point3d ptStart_forced, const Point3d ptEnd_forced,
|
||||
ICurveComposite* pCrv) const
|
||||
SurfFinishing::CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frPocket, const Frame3d& frSurf, const Vector3d& vtTool,
|
||||
double dDepth, const Point3d ptStart_forced, const Point3d ptEnd_forced, ICurveComposite* pCrv) const
|
||||
{
|
||||
// funzione per proiettare una curva su una supericie trimesh passando per la silhouette
|
||||
// controllo dei parametri
|
||||
@@ -5416,25 +5417,9 @@ SurfFinishing::AddPencil( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFinishing::CalcOptimalZigZagCurves( const ISurfFlatRegion* pSfrLoc, const Frame3d& frSurf, const Vector3d& vtTool,
|
||||
SurfFinishing::CalcOptimalZigZagCurves( ISURFFRPOVECTOR& vSfrZigZagProj, const Frame3d& frSurf, const Vector3d& vtTool,
|
||||
double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const
|
||||
{
|
||||
// se la superficie non è valida, non restituisco nulla
|
||||
if ( pSfrLoc == nullptr || ! pSfrLoc->IsValid())
|
||||
return true ;
|
||||
|
||||
// mi assicuro di non uscire dalla superficie originale
|
||||
PtrOwner<ISurfFlatRegion> pMySfrZigZag( CloneSurfFlatRegion( pSfrLoc)) ;
|
||||
if ( IsNull( pMySfrZigZag) || ! pMySfrZigZag->IsValid())
|
||||
return false ;
|
||||
// imposto i lati chiusi
|
||||
for ( int nC = 0 ; nC < pMySfrZigZag->GetChunkCount() ; ++ nC) {
|
||||
for ( int nL = 0 ; nL < pMySfrZigZag->GetLoopCount( nC) ; ++ nL) {
|
||||
for ( int nU = 0 ; nU < pMySfrZigZag->GetLoopCurveCount( nC, nL) ; ++ nU)
|
||||
pMySfrZigZag->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_OPTIMAL_DEBUG
|
||||
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
|
||||
m_pGeomDB->SetName( nGrp, "ZigZag") ;
|
||||
@@ -5444,94 +5429,103 @@ SurfFinishing::CalcOptimalZigZagCurves( const ISurfFlatRegion* pSfrLoc, const Fr
|
||||
int nLaySfrProj = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
|
||||
m_pGeomDB->SetName( nLaySfrProj, "SfrProj") ;
|
||||
m_pGeomDB->SetStatus( nLaySfrProj, GDB_ST_OFF) ;
|
||||
int nSfrProjId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySfrProj, pMySfrZigZag->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( nSfrProjId, Color( 1., 0., 0., .5)) ;
|
||||
#endif
|
||||
|
||||
// controllo se richiesto altro tipo di lavorazione
|
||||
int nSubType = POCKET_ZIGZAG ;
|
||||
if ( GetValInNotes( m_Params.m_sUserNotes, UN_OPTIMALTYPE, nSubType)) {
|
||||
// ammessi ZIG_ZAG, SPIRAL_IN, SPIRAL_OUT
|
||||
if ( nSubType != POCKET_ZIGZAG && nSubType != POCKET_SPIRALIN && nSubType != POCKET_SPIRALOUT)
|
||||
nSubType = POCKET_ZIGZAG ;
|
||||
}
|
||||
|
||||
// per ogni Chunk della superficie a ZigZag, calcolo le curve di lavoro
|
||||
ICRVCOMPOPOVECTOR vCrvCompoZigZag ;
|
||||
for ( int nC = 0 ; nC < pMySfrZigZag->GetChunkCount() ; ++ nC) {
|
||||
// recupero il Chunk corrente
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunk( pMySfrZigZag->CloneChunk( nC)) ;
|
||||
if ( IsNull( pSfrChunk) || ! pMySfrZigZag->IsValid())
|
||||
return false ;
|
||||
// recupero la miglior direzione di orientamento per le curve a ZigZag
|
||||
// --- approssimo il Loop esterno con una PolyLine
|
||||
PolyLine PL ;
|
||||
pSfrChunk->ApproxLoopWithLines( 0, 0, EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) ;
|
||||
// --- porto la PolyLine sul piano locale XY
|
||||
Point3d ptC ; pSfrChunk->GetCentroid( ptC) ;
|
||||
Frame3d frXY ;
|
||||
if ( ! frXY.Set( ptC, pSfrChunk->GetNormVersor()))
|
||||
return false ;
|
||||
PL.ToLoc( frXY) ;
|
||||
pSfrChunk->ToGlob( frSurf) ;
|
||||
// eseguo il calcolo della lavorazione ZigZag
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
if ( ! CalcPocketing( pSfrChunk, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5.,
|
||||
nSubType, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
|
||||
GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) {
|
||||
m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ;
|
||||
return false ;
|
||||
}
|
||||
// memorizzo le curve ricavate
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i)
|
||||
vCrvCompoZigZag.emplace_back( Release( vpCrvs[i])) ;
|
||||
}
|
||||
|
||||
// porto i dati geometrici in locale alle superfici ( proeittando)
|
||||
Vector3d vtAxL = vtTool ;
|
||||
vtAxL.ToLoc( frSurf) ;
|
||||
Vector3d vtMoveL = vtAxL ;
|
||||
const double MIN_DIST = 1. ;
|
||||
const double MAX_DIST = 50. ;
|
||||
double dDist = Clamp( m_Params.m_dApprox, MIN_DIST, MAX_DIST) ;
|
||||
|
||||
// ciclo sui percorsi ricavati
|
||||
double dProgCoeff = 1. / max( int( vCrvCompoZigZag.size()), 1) ;
|
||||
for ( int i = 0 ; i < int( vCrvCompoZigZag.size()) ; ++ i) {
|
||||
// se non valida, passo alla successiva
|
||||
if ( IsNull( vCrvCompoZigZag[i]) || ! vCrvCompoZigZag[i]->IsValid())
|
||||
// Scorro le superfici presenti
|
||||
for ( ISurfFlatRegion* pSfrZigZag : vSfrZigZagProj) {
|
||||
if ( pSfrZigZag == nullptr || ! pSfrZigZag->IsValid())
|
||||
continue ;
|
||||
// correggo il percorso per non interferire con le superfici
|
||||
if ( pCAvTlStm != nullptr) {
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
if ( ! vCrvCompoZigZag[i]->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ||
|
||||
! PL.AdjustForMaxSegmentLen( dDist))
|
||||
return false ;
|
||||
PL.ToLoc( frSurf) ;
|
||||
// traslo della lunghezza utensile diminuita dell'affondamento
|
||||
PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ;
|
||||
// eseguo CAv
|
||||
if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( i + 1) * dProgCoeff))
|
||||
return false ;
|
||||
// contro-traslo della lunghezza utensile
|
||||
PL.Translate( - vtAxL * m_TParams.m_dLen) ;
|
||||
// elimino i punti allineati
|
||||
PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ;
|
||||
// creo una curva composita a partire dalla polilinea
|
||||
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( PL))
|
||||
return false ;
|
||||
|
||||
#if ENABLE_OPTIMAL_DEBUG
|
||||
int nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayCrv, CloneCurveComposite( pCrvCompo)) ;
|
||||
m_pGeomDB->SetMaterial( nCrvId, RED) ;
|
||||
#endif
|
||||
// tutti i lati della superficie vengono considerati come chiusi, quindi per portare l'utensile lungo
|
||||
// i bordi estendo la superficie del raggio utensile
|
||||
if ( ! pSfrZigZag->Offset( m_TParams.m_dDiam / 2. - 5. * EPS_SMALL, ICurve::OFF_FILLET))
|
||||
return false ;
|
||||
for ( int nC = 0 ; nC < pSfrZigZag->GetChunkCount() ; ++ nC) {
|
||||
for ( int nL = 0 ; nL < pSfrZigZag->GetLoopCount( nC) ; ++ nL) {
|
||||
for ( int nU = 0 ; nU < pSfrZigZag->GetLoopCurveCount( nC, nL) ; ++ nU)
|
||||
pSfrZigZag->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ;
|
||||
}
|
||||
}
|
||||
|
||||
// definisco un nuovo percorso
|
||||
vPaths.resize( vPaths.size() + 1) ;
|
||||
vPaths.back().nType = SURFFIN_SUB_ZIGZAG ;
|
||||
vPaths.back().pCrvPath.Set( pCrvCompo) ;
|
||||
#if ENABLE_OPTIMAL_DEBUG
|
||||
int nSfrProjId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySfrProj, pSfrZigZag->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( nSfrProjId, Color( 1., 0., 0., .5)) ;
|
||||
#endif
|
||||
|
||||
// controllo se richiesto altro tipo di lavorazione
|
||||
int nSubType = POCKET_ZIGZAG ;
|
||||
if ( GetValInNotes( m_Params.m_sUserNotes, UN_OPTIMALTYPE, nSubType)) {
|
||||
// ammessi ZIG_ZAG, SPIRAL_IN, SPIRAL_OUT
|
||||
if ( nSubType != POCKET_ZIGZAG && nSubType != POCKET_SPIRALIN && nSubType != POCKET_SPIRALOUT)
|
||||
nSubType = POCKET_ZIGZAG ;
|
||||
}
|
||||
|
||||
// per ogni Chunk della superficie a ZigZag, calcolo le curve di lavoro
|
||||
ICRVCOMPOPOVECTOR vCrvCompoZigZag ;
|
||||
for ( int nC = 0 ; nC < pSfrZigZag->GetChunkCount() ; ++ nC) {
|
||||
// recupero il Chunk corrente
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunk( pSfrZigZag->CloneChunk( nC)) ;
|
||||
if ( IsNull( pSfrChunk) || ! pSfrZigZag->IsValid())
|
||||
return false ;
|
||||
// porto il Chunk in Globale
|
||||
pSfrChunk->ToGlob( frSurf) ;
|
||||
// eseguo il calcolo della lavorazione ZigZag
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
if ( ! CalcPocketing( pSfrChunk, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5.,
|
||||
nSubType, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
|
||||
GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) {
|
||||
m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ;
|
||||
return false ;
|
||||
}
|
||||
// memorizzo le curve ricavate
|
||||
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i)
|
||||
vCrvCompoZigZag.emplace_back( Release( vpCrvs[i])) ;
|
||||
}
|
||||
|
||||
// porto i dati geometrici in locale alle superfici ( proeittando)
|
||||
Vector3d vtAxL = vtTool ;
|
||||
vtAxL.ToLoc( frSurf) ;
|
||||
Vector3d vtMoveL = vtAxL ;
|
||||
const double MIN_DIST = 1. ;
|
||||
const double MAX_DIST = 50. ;
|
||||
double dDist = Clamp( m_Params.m_dApprox, MIN_DIST, MAX_DIST) ;
|
||||
|
||||
// ciclo sui percorsi ricavati
|
||||
double dProgCoeff = 1. / max( static_cast<int>( ssize( vCrvCompoZigZag)), 1) ;
|
||||
for ( int i = 0 ; i < ssize( vCrvCompoZigZag) ; ++ i) {
|
||||
// se non valida, passo alla successiva
|
||||
if ( IsNull( vCrvCompoZigZag[i]) || ! vCrvCompoZigZag[i]->IsValid())
|
||||
continue ;
|
||||
// correggo il percorso per non interferire con le superfici
|
||||
if ( pCAvTlStm != nullptr) {
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
if ( ! vCrvCompoZigZag[i]->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ||
|
||||
! PL.AdjustForMaxSegmentLen( dDist))
|
||||
return false ;
|
||||
PL.ToLoc( frSurf) ;
|
||||
// traslo della lunghezza utensile diminuita dell'affondamento
|
||||
PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ;
|
||||
// eseguo CAv
|
||||
if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( i + 1) * dProgCoeff))
|
||||
return false ;
|
||||
// contro-traslo della lunghezza utensile
|
||||
PL.Translate( - vtAxL * m_TParams.m_dLen) ;
|
||||
// elimino i punti allineati
|
||||
PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ;
|
||||
// creo una curva composita a partire dalla polilinea
|
||||
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( PL))
|
||||
return false ;
|
||||
#if ENABLE_OPTIMAL_DEBUG
|
||||
int nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayCrv, CloneCurveComposite( pCrvCompo)) ;
|
||||
m_pGeomDB->SetMaterial( nCrvId, RED) ;
|
||||
#endif
|
||||
// definisco un nuovo percorso
|
||||
vPaths.resize( vPaths.size() + 1) ;
|
||||
vPaths.back().nType = SURFFIN_SUB_ZIGZAG ;
|
||||
vPaths.back().pCrvPath.Set( pCrvCompo) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5540,15 +5534,13 @@ SurfFinishing::CalcOptimalZigZagCurves( const ISurfFlatRegion* pSfrLoc, const Fr
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SURFLOCALVECTOR& vSrfLoc,
|
||||
const Frame3d& frSurf, const Vector3d& vtTool, double dAngDegSplit,
|
||||
double dAngDegTol, double dDepth, ICAvToolSurfTm* pCAvTlStm,
|
||||
VECTORPATHS& vPaths, ISurfFlatRegion* pSfrProj) const
|
||||
SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
|
||||
const Vector3d& vtTool, double dAngDegSplit, double dAngDegTol, double dDepth,
|
||||
ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const
|
||||
{
|
||||
// se la superficie non è valida, non restituisco nulla
|
||||
if ( pSfrLoc == nullptr || ! pSfrLoc->IsValid())
|
||||
return true ;
|
||||
pSfrProj->Clear() ;
|
||||
|
||||
// mi assicuro di non uscire dalla superficie originale
|
||||
PtrOwner<ISurfFlatRegion> pMySfrZConst( CloneSurfFlatRegion( pSfrLoc)) ;
|
||||
@@ -5564,7 +5556,7 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
// inizializzo la classe di calcolo delle silhouette
|
||||
CISURFTMPVECTOR vpStm ; vpStm.reserve( vSrfLoc.size()) ;
|
||||
// scorro le superfici
|
||||
for ( int i = 0 ; i < int( vSrfLoc.size()) ; ++ i) {
|
||||
for ( int i = 0 ; i < ssize( vSrfLoc) ; ++ i) {
|
||||
// recupero la superficie
|
||||
const ISurf* pSurf = GetSurf( vSrfLoc[i].Get()) ;
|
||||
if ( pSurf == nullptr || ! pSurf->IsValid())
|
||||
@@ -5599,8 +5591,8 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
// inizializzo classe di calcolo per le curve a ZConst con utensile corrente
|
||||
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
|
||||
if ( IsNull( pCavParSilh) ||
|
||||
! pCavParSilh->SetData( vpStm, frSfr, SILH_SAMPLING, m_TParams.m_dSideAng, m_TParams.m_dDiam,
|
||||
m_TParams.m_dCornRad, m_TParams.m_dMaxMat, GetOffsR(), dDepth))
|
||||
! pCavParSilh->SetData( vpStm, frSfr, SILH_SAMPLING, m_TParams.m_dSideAng, m_TParams.m_dDiam, m_TParams.m_dCornRad,
|
||||
m_TParams.m_dMaxMat, GetOffsR(), dDepth))
|
||||
return false ;
|
||||
|
||||
// recupero le curve singole definite dal bordo della Silhouette
|
||||
@@ -5617,7 +5609,6 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
// --- versore direzione utensile e versore direzione movimento
|
||||
Vector3d vtAxL = vtTool ;
|
||||
vtAxL.ToLoc( frSurf) ;
|
||||
Vector3d vtMoveL = vtAxL ;
|
||||
// --- tolleranza di campionamento per punti della PolyLine
|
||||
const double MIN_DIST = 1. ;
|
||||
const double MAX_DIST = 50. ;
|
||||
@@ -5657,7 +5648,7 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
#endif
|
||||
|
||||
// scorro i piani di ZConst ricavati...
|
||||
for ( int i = 0 ; i < int( vvCrvCompo.size()) ; ++ i) {
|
||||
for ( int i = 0 ; i < ssize( vvCrvCompo) ; ++ i) {
|
||||
// Dalle curve si ricavano le PolyLine corrispondeti e vengono suddivise in 3 categorie :
|
||||
// - PolyLine valide : definite da punti di campionamento consecutivi dove esiste una normale di
|
||||
// di collisione con angolo rispetto a vtTool > dSplitAngDeg
|
||||
@@ -5671,8 +5662,8 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
// la distanza dalla Sfr è memorizzata nel primo TempParam [*]
|
||||
double dSfrDist = 0. ;
|
||||
|
||||
// per il piano corrente scorro le curve di Silhouette ricavate...
|
||||
for ( int j = 0 ; j < int( vvCrvCompo[i].size()) ; ++ j) {
|
||||
// per il piano corrente scorro le curve di Silhouette ricavate
|
||||
for ( int j = 0 ; j < ssize( vvCrvCompo[i]) ; ++ j) {
|
||||
// se curva non valida, passo alla successiva
|
||||
if ( IsNull( vvCrvCompo[i][j]) || ! vvCrvCompo[i][j]->IsValid())
|
||||
continue ;
|
||||
@@ -5690,44 +5681,39 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
return false ;
|
||||
|
||||
// scorro i punti della PolyLine e li calssifico
|
||||
for ( POINTU& ptU : PL.GetUPointList()) {
|
||||
for ( const POINTU& ptU : PL.GetUPointList()) {
|
||||
// La curva di Silhouette, una volta approssimata, può presentare alcuni punti quel poco
|
||||
// che basta più lontani dalla superficie per non ricavare alcuna collisione.
|
||||
// NB. le curve ricavate sono approssimate, mergiate e leggermente smussate.
|
||||
// --> In questo caso sposto leggermente il punto verso la superficie
|
||||
// NB. Le curve di Silhoette per definizione sono orientate lasciando le vStm alla loro destra
|
||||
// NB. Le curve ricavate sono approssimate, mergiate e leggermente smussate.
|
||||
// --> In questo caso sposto leggermente il punto verso la superficie ( algoritmo iterativo fino a collisione individuata)
|
||||
// NB. Le curve di Silhouette per definizione sono orientate lasciando le vStm alla loro destra
|
||||
int nPointType = DISCARD ;
|
||||
double dPar ;
|
||||
Point3d ptShift ;
|
||||
Vector3d vtIn ;
|
||||
VCT3DVECTOR vVtN ;
|
||||
if ( vvCrvCompo[i][j]->GetParamAtPoint( ptU.first, dPar, 10 * EPS_SMALL) &&
|
||||
vvCrvCompo[i][j]->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptShift, &vtIn)) {
|
||||
ptShift.Translate( - vtAxL * m_TParams.m_dLen) ; // per ricavare la colisione
|
||||
vtIn.Normalize() ;
|
||||
vtIn.Rotate( vtAxL, ! m_Params.m_bInvert ? ANG_RIGHT : - ANG_RIGHT) ;
|
||||
const double MAXSHIFT = SILH_SAMPLING ;
|
||||
const int SAMPLETOL = 10 ;
|
||||
double dShift = MAXSHIFT / ( 1. * SAMPLETOL) ;
|
||||
for ( int i = 1 ; i < SAMPLETOL && vVtN.empty() ; ++ i) {
|
||||
ptShift.Translate( vtIn * ( i * dShift)) ; // leggero spostamento del punto
|
||||
double dToTDist = 0. ;
|
||||
// calcolo la collisione
|
||||
if ( ! pCAvTlStm->TestPositionAdv( ptShift, vtAxL, vtMoveL, dToTDist, vVtN))
|
||||
return false ;
|
||||
// classificazione del punto
|
||||
if ( ! vVtN.empty()) {
|
||||
for ( Vector3d& vtN : vVtN) {
|
||||
if ( abs( vtN * vtAxL) < dCosLimit) {
|
||||
nPointType = VALID ;
|
||||
break ;
|
||||
}
|
||||
else if ( abs( vtN * vtAxL) < dCosUpperBound)
|
||||
nPointType = AMBIGUOUS ;
|
||||
}
|
||||
VCT3DLIST vvtN ;
|
||||
double dMinDist = INFINITO - 1 ;
|
||||
for ( int nSurf = 0 ; nSurf < ssize( vpStm) ; ++ nSurf) {
|
||||
DistPointSurfTm distPtSurfTm( ptU.first, *vpStm[nSurf]) ;
|
||||
double dMyDist = INFINITO - 2 ;
|
||||
if ( distPtSurfTm.GetDist( dMyDist) && dMyDist < dMinDist) {
|
||||
dMinDist = dMyDist ;
|
||||
INTVECTOR vTriaMinDist ; distPtSurfTm.GetMinDistTriaIndices( vTriaMinDist) ;
|
||||
Triangle3d Tria ;
|
||||
for ( const int& nTria : vTriaMinDist) {
|
||||
vpStm[nSurf]->GetTriangle( nTria, Tria) ;
|
||||
vvtN.push_back( Tria.GetN()) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// classificazione del punto
|
||||
if ( ! vvtN.empty()) {
|
||||
for ( const Vector3d& vtN : vvtN) {
|
||||
if ( abs( vtN * vtAxL) < dCosLimit) {
|
||||
nPointType = VALID ;
|
||||
break ;
|
||||
}
|
||||
else if ( abs( vtN * vtAxL) < dCosUpperBound)
|
||||
nPointType = AMBIGUOUS ;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_OPTIMAL_DEBUG
|
||||
PtrOwner<IGeoPoint3d> pt( CreateGeoPoint3d()) ;
|
||||
@@ -5735,7 +5721,7 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayPt, Release( pt)) ;
|
||||
m_pGeomDB->SetMaterial( a, nPointType == VALID ? GREEN :
|
||||
nPointType == AMBIGUOUS ? LIME : BLACK) ;
|
||||
for ( Vector3d& vtN : vVtN) {
|
||||
for ( Vector3d& vtN : vvtN) {
|
||||
PtrOwner<IGeoVector3d> vt( CreateGeoVector3d()) ;
|
||||
vt->Set( vtN) ;
|
||||
vt->Translate( ptU.first - ORIG) ;
|
||||
@@ -5762,7 +5748,7 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
|
||||
// costruisco le PolyLine definitive
|
||||
bool bFirst = true ;
|
||||
int nPL = int( vTypePL.size()) ;
|
||||
int nPL = ssize( vTypePL) ;
|
||||
for ( int nInd = 0 ; nInd < nPL ; ++ nInd) {
|
||||
// se tratto valido
|
||||
if ( vTypePL[nInd].first == VALID) {
|
||||
@@ -5775,29 +5761,28 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
bFirst = false ;
|
||||
}
|
||||
// se tratto precedente ambiguo, lo aggiungo al tratto corrente e lo rendo invalido
|
||||
if ( nPL > 1 &&
|
||||
( vTypePL[nPrevInd].first == AMBIGUOUS || vTypePL[nPrevInd].first == VALID)) {
|
||||
// controllo che i punti siano sufficientemente vicini ( sqrt(2) * dDist))
|
||||
if ( nPL > 1 && ( vTypePL[nPrevInd].first == AMBIGUOUS || vTypePL[nPrevInd].first == VALID)) {
|
||||
// controllo che i punti siano sufficientemente vicini ( sqrt( 2) * dDist))
|
||||
Point3d ptBack, ptCurr ;
|
||||
vTypePL[nPrevInd].second.GetLastPoint( ptBack) ;
|
||||
vTypePL[nInd].second.GetFirstPoint( ptCurr) ;
|
||||
if ( AreSamePointEpsilon( ptBack, ptCurr, 2 * dDist * dDist)) {
|
||||
for ( auto& ptU : vTypePL[nPrevInd].second.GetUPointList())
|
||||
if ( AreSamePointEpsilon( ptBack, ptCurr, SQRT2 * dDist)) {
|
||||
for ( const POINTU& ptU : vTypePL[nPrevInd].second.GetUPointList())
|
||||
vPL.back().AddUPoint( 0., ptU.first) ;
|
||||
vTypePL[nPrevInd].first = DISCARD ;
|
||||
}
|
||||
}
|
||||
// aggiungo il tratto corrente e lo rendo invalido
|
||||
for ( auto& ptU : vTypePL[nInd].second.GetUPointList())
|
||||
for ( const POINTU& ptU : vTypePL[nInd].second.GetUPointList())
|
||||
vPL.back().AddUPoint( 0., ptU.first) ;
|
||||
vTypePL[nInd].first = DISCARD ;
|
||||
// se tratto successivo ambiguo, lo aggiungo al tratto corrente e lo rendo invalido
|
||||
if ( vTypePL[nAfterInd].first == AMBIGUOUS) {
|
||||
// controllo che i punti siano sufficientemente vicini ( sqrt(2) * dDist))
|
||||
// controllo che i punti siano sufficientemente vicini ( sqrt( 2) * dDist))
|
||||
Point3d ptForward, ptCurr ;
|
||||
vTypePL[nAfterInd].second.GetFirstPoint( ptForward) ;
|
||||
vTypePL[nInd].second.GetLastPoint( ptCurr) ;
|
||||
if ( AreSamePointEpsilon( ptForward, ptCurr, 2 * dDist * dDist)) {
|
||||
if ( AreSamePointEpsilon( ptForward, ptCurr, SQRT2 * dDist)) {
|
||||
for ( auto& ptU : vTypePL[nAfterInd].second.GetUPointList())
|
||||
vPL.back().AddUPoint( 0., ptU.first) ;
|
||||
vTypePL[nAfterInd].first = DISCARD ;
|
||||
@@ -5810,14 +5795,46 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
bFirst = true ;
|
||||
}
|
||||
|
||||
// verifico se inizio e fine delle PolyLine sono sufficientemente vicine, in caso positivo unisco in una PolyLine unica
|
||||
if ( ssize( vPL) == 1 && vPL[0].GetPointNbr() > 1 && ! vPL[0].IsClosed()) {
|
||||
Point3d ptStart ; vPL[0].GetFirstPoint( ptStart) ;
|
||||
Point3d ptEnd ; vPL[0].GetLastPoint( ptEnd) ;
|
||||
if ( AreSamePointEpsilon( ptStart, ptEnd, SQRT2 * dDist))
|
||||
vPL[0].Close() ;
|
||||
}
|
||||
else if ( ssize( vPL) > 1) {
|
||||
BOOLVECTOR vbSkipIndex ; vbSkipIndex.resize( vPL.size()) ;
|
||||
for ( int i = 0 ; i < ssize( vPL) ; ++ i)
|
||||
vbSkipIndex[i] = ( vPL[i].IsClosed()) ;
|
||||
for ( int i = 0 ; i < ssize( vPL) ; ++ i) {
|
||||
if ( ! vbSkipIndex[i]) {
|
||||
Point3d ptEnd ; vPL[i].GetLastPoint( ptEnd) ;
|
||||
for ( int j = 0 ; j < ssize( vPL) ; ++ j) {
|
||||
if ( j != i && ! vbSkipIndex[j]) {
|
||||
Point3d ptStart ; vPL[j].GetFirstPoint( ptStart) ;
|
||||
if ( AreSamePointEpsilon( ptStart, ptEnd, SQRT2 * dDist)) {
|
||||
for ( POINTU& ptU : vPL[j].GetUPointList())
|
||||
vPL[i].AddUPoint( 0., ptU.first) ;
|
||||
vbSkipIndex[j] = true ;
|
||||
vPL[j].Clear() ;
|
||||
-- i ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dalle PolyLine recupero le curve
|
||||
vvCrvCompo[i].clear() ;
|
||||
for ( PolyLine& PL : vPL) {
|
||||
for ( const PolyLine& PL : vPL) {
|
||||
// se vuota, non faccio nulla
|
||||
if ( PL.GetPointNbr() < 2)
|
||||
continue ;
|
||||
// se PolyLine troppo corta, non la memorizzo ( < 1/4 circonferenza utensile)
|
||||
double dLen = 0. ;
|
||||
PL.GetLength( dLen) ;
|
||||
double dLen = 0. ; PL.GetLength( dLen) ;
|
||||
if ( dLen < ( PIGRECO / 2.) * ( m_TParams.m_dDiam / 2.))
|
||||
continue ;
|
||||
// definisco la curva e la abbellisco
|
||||
@@ -5830,46 +5847,11 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
vvCrvCompo[i].back()->SetTempParam( dSfrDist, 0) ;
|
||||
#if ENABLE_OPTIMAL_DEBUG
|
||||
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayCrv, vvCrvCompo[i].back()->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( a, GREEN) ;
|
||||
m_pGeomDB->SetMaterial( a, FUCHSIA) ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// NB. per determinare la regione da lavavorare a ZigZag, devo prima determinare la regione
|
||||
// definita dalle curve ZConst.
|
||||
// --- determino il piano di proiezione dalla regione originale
|
||||
Plane3d plProj ;
|
||||
if ( ! plProj.Set( ptC, vtAxL))
|
||||
return false ;
|
||||
// --- per ogni curva valida, definisco una regione piana Fat sul piano calcolato
|
||||
for ( auto& vCrvCompo : vvCrvCompo) {
|
||||
for ( auto& pCrvCompo : vCrvCompo) {
|
||||
// se curva non valida, passo alla successiva
|
||||
if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid())
|
||||
continue ;
|
||||
// proeitto la curva sul piano
|
||||
PtrOwner<ICurve> pCrvProj( ProjectCurveOnPlane( *pCrvCompo, plProj)) ;
|
||||
if ( IsNull( pCrvProj) || ! pCrvProj->IsValid())
|
||||
continue ;
|
||||
// determino la sua FatRegion
|
||||
pCrvProj->SetExtrusion( vtAxL) ; // per coprire eventuali regioni fini
|
||||
PtrOwner<ISurfFlatRegion> pSfrFat( GetSurfFlatRegionFromFatCurve( pCrvProj->Clone(), m_Params.m_dSideStep / dCosLimit, false, false)) ;
|
||||
if ( IsNull( pSfrFat) || ! pSfrFat->IsValid())
|
||||
continue ;
|
||||
if ( AreOppositeVectorApprox( pSfrFat->GetNormVersor(), vtAxL))
|
||||
pSfrFat->Invert() ;
|
||||
// aggiungo questa regione a quella complessiva
|
||||
if ( pSfrProj->IsValid() && pSfrProj->GetChunkCount() > 0)
|
||||
pSfrProj->Add( *pSfrFat) ;
|
||||
else
|
||||
pSfrProj->CopyFrom( pSfrFat) ;
|
||||
}
|
||||
}
|
||||
#if ENABLE_OPTIMAL_DEBUG
|
||||
int nSfrId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySfrProj, pSfrProj->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( nSfrId, Color( 0., 1., 0., .5)) ;
|
||||
#endif
|
||||
|
||||
// collego tra loro le curve trovate definendo quindi un percorso
|
||||
ICRVCOMPOPOVECTOR vCrv ;
|
||||
if ( ! CreateZConstPaths( pCAvTlStm, frSurf, vvCrvCompo, vtTool, pMySfrZConst, dDepth, vCrv)) {
|
||||
@@ -5878,7 +5860,7 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
}
|
||||
|
||||
// restituisco i percorsi trovati
|
||||
for ( int i = 0 ; i < int( vCrv.size()) ; ++ i) {
|
||||
for ( int i = 0 ; i < ssize( vCrv) ; ++ i) {
|
||||
vPaths.resize( vPaths.size() + 1) ;
|
||||
vPaths.back().pCrvPath.Set( Release( vCrv[i])) ;
|
||||
vPaths.back().nType = SURFFIN_SUB_Z_CONST ;
|
||||
@@ -5887,74 +5869,267 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFinishing::AreSameSfrChunkEpsilon( const ISurfFlatRegion* pSfrChunkA, const ISurfFlatRegion* pSfrChunkB, double dMaxDist) const
|
||||
{
|
||||
// se esiste una superficie non valida, sicuro le superfici non sono sovrapposte
|
||||
if ( pSfrChunkA == nullptr || pSfrChunkB == nullptr || ! pSfrChunkA->IsValid() || ! pSfrChunkB->IsValid())
|
||||
return false ;
|
||||
|
||||
// Verifico che le sueprfici siano orientate correntamente
|
||||
if ( ! AreSameVectorApprox( pSfrChunkA->GetNormVersor(), pSfrChunkB->GetNormVersor()))
|
||||
return false ;
|
||||
|
||||
double dMyMaxDist = max( 10. * EPS_SMALL, dMaxDist) ;
|
||||
|
||||
// verifico mediate FatCurves dei bordi se in tolleranza
|
||||
PtrOwner<ICurve> pCrvExtBorderA( pSfrChunkA->GetLoop( 0, 0)) ;
|
||||
PtrOwner<ICurve> pCrvExtBorderB( pSfrChunkB->GetLoop( 0, 0)) ;
|
||||
if ( IsNull( pCrvExtBorderA) || IsNull( pCrvExtBorderB) || ! pCrvExtBorderA->IsValid() || ! pCrvExtBorderB->IsValid())
|
||||
return false ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrFatExtA( GetSurfFlatRegionFromFatCurve( pCrvExtBorderA->Clone(), dMyMaxDist, false, false)) ;
|
||||
if ( IsNull( pSfrFatExtA) || ! pSfrFatExtA->IsValid())
|
||||
return false ;
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! pSfrFatExtA->GetCurveClassification( *pCrvExtBorderB, EPS_SMALL, ccClass) ||
|
||||
! ( ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_IN))
|
||||
return false ;
|
||||
|
||||
// Recupero la superficie con più isole
|
||||
int nIslA = pSfrFatExtA->GetLoopCount( 0) - 1 ;
|
||||
int nIslB = pSfrChunkB->GetLoopCount( 0) - 1 ;
|
||||
if ( nIslA == 0 && nIslB == 0)
|
||||
return true ;
|
||||
|
||||
const ISurfFlatRegion* pSfrA = ( nIslA >= nIslB ? pSfrChunkA : pSfrChunkB) ;
|
||||
const ISurfFlatRegion* pSfrB = ( nIslA < nIslB ? pSfrChunkA : pSfrChunkB) ;
|
||||
if ( pSfrA == nullptr || pSfrB == nullptr)
|
||||
return false ;
|
||||
|
||||
// Regioni di Controllo
|
||||
ISURFFRPOVECTOR vFatSurfA ; vFatSurfA.reserve( nIslA) ;
|
||||
for ( int nIsl = 0 ; nIsl < nIslA ; ++ nIsl) {
|
||||
PtrOwner<ICurve> pCrvIsl( pSfrA->GetLoop( 0, nIsl + 1)) ;
|
||||
if ( ! IsNull( pCrvIsl) && pCrvIsl->IsValid()) {
|
||||
PtrOwner<ISurfFlatRegion> pSfrFat( GetSurfFlatRegionFromFatCurve( pCrvIsl->Clone(), dMaxDist, false, false)) ;
|
||||
if ( ! IsNull( pSfrFat) && pSfrFat->IsValid()) {
|
||||
if ( ! vFatSurfA.emplace_back( Release( pSfrFat)))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop dell'altra regione
|
||||
for ( int nIsl = 0 ; nIsl < nIslB ; ++ nIsl) {
|
||||
PtrOwner<ICurve> pCrvIsl( pSfrB->GetLoop( 0, nIsl + 1)) ;
|
||||
if ( ! IsNull( pCrvIsl) && pCrvIsl->IsValid()) {
|
||||
// Se curva troppo stretta, non la considero
|
||||
OffsetCurve OffsCrv ;
|
||||
if ( OffsCrv.Make( pCrvIsl, dMaxDist, ICurve::OFF_FILLET)) {
|
||||
PtrOwner<ICurve> pCrv( OffsCrv.GetLongerCurve()) ;
|
||||
if ( IsNull( pCrv) || ! pCrv->IsValid())
|
||||
continue ;
|
||||
}
|
||||
// verifico che esista una regione Fat che la contenga
|
||||
bool bOk = true ;
|
||||
for ( const ISurfFlatRegion* pSfrFat : vFatSurfA) {
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( pSfrFat->GetCurveClassification( *pCrvExtBorderB, EPS_SMALL, ccClass) &&
|
||||
ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_IN) {
|
||||
bOk = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( ! bOk)
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFinishing::CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
|
||||
const Vector3d& vtToolLoc, double dDepth, double dSplitAngDeg, ISURFFRPOVECTOR& vpSfrZigZagProj) const
|
||||
{
|
||||
// verifico validità dei parametri
|
||||
if ( pSfrCntLoc == nullptr || ! pSfrCntLoc->IsValid())
|
||||
return false ;
|
||||
vpSfrZigZagProj.clear() ;
|
||||
|
||||
const double COS_SPLIT_ANG = cos( dSplitAngDeg * DEGTORAD) ;
|
||||
|
||||
// scorro tutte le facce delle superfici presenti
|
||||
CISURFTMPVECTOR vpStm ; vpStm.reserve( vSrfLoc.size()) ;
|
||||
for ( const SurfLocal& SurfL : vSrfLoc) {
|
||||
// recupero la superficie
|
||||
const ISurf* pSurf = GetSurf( SurfL.Get()) ;
|
||||
if ( pSurf == nullptr || ! pSurf->IsValid())
|
||||
continue ;
|
||||
int nType = pSurf->GetType() ;
|
||||
// se TriMesh
|
||||
if ( nType == SRF_TRIMESH) {
|
||||
const ISurfTriMesh* pStm = GetSurfTriMesh( pSurf) ;
|
||||
if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0)
|
||||
vpStm.emplace_back( pStm) ;
|
||||
}
|
||||
// se Bezier
|
||||
else if ( nType == SRF_BEZIER) {
|
||||
const ISurfBezier* pSBz = GetSurfBezier( pSurf) ;
|
||||
if ( pSBz != nullptr && pSBz->IsValid()) {
|
||||
double dOldTol = GetSurfBezierAuxSurfRefinedTol() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( 5. * EPS_SMALL) ;
|
||||
const ISurfTriMesh* pStm = pSBz->GetAuxSurfRefined() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( dOldTol) ;
|
||||
if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0)
|
||||
vpStm.emplace_back( pStm) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Definisco una Zuppa di Triangoli per le facce entro la tolleranza
|
||||
StmFromTriangleSoup StmSoup ;
|
||||
StmSoup.Start() ;
|
||||
for ( const ISurfTriMesh* pStm : vpStm) {
|
||||
if ( pStm == nullptr || ! pStm->IsValid())
|
||||
continue ;
|
||||
// scorro le faccie della superficie e controllo l'angolo presente
|
||||
for ( int nF = 0 ; nF < pStm->GetFacetCount() ; ++ nF) {
|
||||
Vector3d vtFaceN ; pStm->GetFacetNormal( nF, vtFaceN) ;
|
||||
if ( vtFaceN * vtToolLoc > COS_SPLIT_ANG) {
|
||||
INTVECTOR vnTria ; pStm->GetAllTriaInFacet( nF, vnTria) ;
|
||||
for ( const int& nT : vnTria) {
|
||||
Triangle3d Tria ; pStm->GetTriangle( nT, Tria) ;
|
||||
StmSoup.AddTriangle( Tria) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StmSoup.End() ;
|
||||
|
||||
// recupero i parametri per il calcolo delle regioni piane a ZigZag
|
||||
Point3d ptTop ; pSfrCntLoc->GetCentroid( ptTop) ;
|
||||
Frame3d frPlanes ;
|
||||
if ( ! frPlanes.Set( ptTop, vtToolLoc))
|
||||
return false ;
|
||||
const double TOL_SIL = 1.0 ;
|
||||
INTDBLVECTOR vSfrDistInd ;
|
||||
|
||||
// Recupero le Superfici TriMesh
|
||||
PtrOwner<ISurfTriMesh> pStmZigZag( StmSoup.GetSurf()) ;
|
||||
while ( ! IsNull( pStmZigZag)) {
|
||||
if ( pStmZigZag->IsValid() && pStmZigZag->GetTriangleCount() > 0) {
|
||||
// ogni Part della TriMesh a ZigZag diventa una FlatRegion
|
||||
for ( int nP = 0 ; nP < pStmZigZag->GetPartCount() ; ++ nP) {
|
||||
PtrOwner<ISurfTriMesh> pStmZigZagPart( pStmZigZag->ClonePart( nP)) ;
|
||||
if ( ! IsNull( pStmZigZagPart) && pStmZigZagPart->IsValid()) {
|
||||
// recupero il Box della Parte corrente e determino la quota media ( controllo basilare, migliorabile)
|
||||
BBox3d BBoxPart ;
|
||||
pStmZigZagPart->GetLocalBBox( BBoxPart) ;
|
||||
Point3d ptMid ; BBoxPart.GetCenter( ptMid) ;
|
||||
// recupero le PolyLine di proiezione per la definizione del bordo
|
||||
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
|
||||
if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( {pStmZigZagPart}, frPlanes, TOL_SIL))
|
||||
return false ;
|
||||
POLYLINEVECTOR vPL ;
|
||||
if ( ! pCavParSilh->GetSilhouette( - dDepth, vPL))
|
||||
return false ;
|
||||
// inizializzo classe di calcolo per regione piana corrente mediante le PolyLine ricavate
|
||||
SurfFlatRegionByContours SfrByC ;
|
||||
for ( const PolyLine& PL : vPL) {
|
||||
PtrOwner<ICurveComposite> pCompoPL( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCompoPL) || ! pCompoPL->FromPolyLine( PL) || ! SfrByC.AddCurve( pCompoPL->Clone()))
|
||||
return false ;
|
||||
}
|
||||
// Recupero le superfici piane e le memorizzo
|
||||
PtrOwner<ISurfFlatRegion> pSfrProj( SfrByC.GetSurf()) ;
|
||||
while ( ! IsNull( pSfrProj)) {
|
||||
if ( pSfrProj->IsValid()) {
|
||||
// porto la superficie in Globale
|
||||
if ( AreOppositeVectorEpsilon( pSfrProj->GetNormVersor(), vtToolLoc, 20. * EPS_SMALL))
|
||||
pSfrProj->Invert() ;
|
||||
// limito questa regione all'intersezione con la superficie di Contorno
|
||||
if ( ! pSfrProj->Intersect( *pSfrCntLoc))
|
||||
return false ;
|
||||
if ( pSfrProj->IsValid()) {
|
||||
// verifico che non ci siano delle superfici duplicate
|
||||
bool bDuplicate = false ;
|
||||
for ( int i = 0 ; ! bDuplicate && i < ssize( vpSfrZigZagProj) ; ++ i)
|
||||
bDuplicate = AreSameSfrChunkEpsilon( pSfrProj, vpSfrZigZagProj[i], m_TParams.m_dDiam / 4.) ;
|
||||
if ( ! bDuplicate) {
|
||||
vpSfrZigZagProj.emplace_back( Release( pSfrProj)) ;
|
||||
vSfrDistInd.emplace_back( make_pair( ssize( vpSfrZigZagProj) - 1, abs( ( ptMid - ptTop) * vtToolLoc))) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
pSfrProj.Set( SfrByC.GetSurf()) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pStmZigZag.Set( StmSoup.GetSurf()) ;
|
||||
}
|
||||
if ( ssize( vpSfrZigZagProj) < 2)
|
||||
return true ;
|
||||
|
||||
// ordino le superfici ottenute in base alla distanza con la Superficie di contorno ( riferita alla Part di TriMesh)
|
||||
ranges::sort( vSfrDistInd, {}, &pair<int, double>::second) ;
|
||||
for ( int i = 0 ; i < ssize( vSfrDistInd) ; ++ i) {
|
||||
int nCurrI = i ;
|
||||
while ( vSfrDistInd[nCurrI].first != nCurrI) {
|
||||
int nNextI = vSfrDistInd[nCurrI].first ;
|
||||
swap( vpSfrZigZagProj[nCurrI], vpSfrZigZagProj[nNextI]) ;
|
||||
swap( vSfrDistInd[nCurrI], vSfrDistInd[nNextI]) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
|
||||
const ISurfFlatRegion* pSfrCntZigZag, const ISurfFlatRegion* pSfrCntZConst,
|
||||
const ISurfFlatRegion* pSfrCnt, const ISurfFlatRegion* pSfrCntExt,
|
||||
const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs)
|
||||
{
|
||||
// vettore dei percorsi da calcolare
|
||||
VECTORPATHS vPaths ;
|
||||
|
||||
// se entrambe le regioni non sono valide, non faccio nulla
|
||||
if ( ( pSfrCntZigZag == nullptr || ! pSfrCntZigZag->IsValid()) &&
|
||||
( pSfrCntZConst == nullptr || ! pSfrCntZConst->IsValid()))
|
||||
if ( ( pSfrCnt == nullptr || ! pSfrCnt->IsValid()) && ( pSfrCntExt == nullptr || ! pSfrCntExt->IsValid()))
|
||||
return false ;
|
||||
|
||||
// recupero l'angolo di Split e la rispettiva tolleranza
|
||||
double dAngDegSplit = 45 ;
|
||||
GetValInNotes( m_Params.m_sUserNotes, UN_SPLITANGLE, dAngDegSplit) ;
|
||||
double dAngDegTol = 5 ;
|
||||
GetValInNotes( m_Params.m_sUserNotes, UN_ANGLETOL, dAngDegTol) ;
|
||||
double dAngDegSplit = 45. ; GetValInNotes( m_Params.m_sUserNotes, UN_SPLITANGLE, dAngDegSplit) ;
|
||||
double dAngDegTol = 5. ; GetValInNotes( m_Params.m_sUserNotes, UN_ANGLETOL, dAngDegTol) ;
|
||||
|
||||
// inizializzo l'area di lavoro determinata dalle curve ZigZag
|
||||
PtrOwner<ISurfFlatRegion> pSfrZigZagProjLoc ;
|
||||
if ( pSfrCntZigZag != nullptr && pSfrCntZigZag->IsValid()) {
|
||||
if ( ! pSfrZigZagProjLoc.Set( CloneSurfFlatRegion( pSfrCntZigZag)) ||
|
||||
! pSfrCntZigZag->IsValid())
|
||||
return false ;
|
||||
pSfrZigZagProjLoc->ToLoc( frSurf) ;
|
||||
}
|
||||
else {
|
||||
if ( ! pSfrZigZagProjLoc.Set( CreateSurfFlatRegion()))
|
||||
return false ;
|
||||
// tengo una copia della regione di contorno in locale alle superfici
|
||||
PtrOwner<ISurfFlatRegion> pSfrCntLoc( CloneSurfFlatRegion( pSfrCnt)) ;
|
||||
if ( IsNull( pSfrCntLoc) || ! pSfrCntLoc->IsValid() || ! pSfrCntLoc->ToLoc( frSurf))
|
||||
return false ;
|
||||
|
||||
// --- [1°] calcolo delle curve ZLevel e [2°] definizione della regione di proiezione per Zlevel ---
|
||||
PtrOwner<ISurfFlatRegion> pSfrCntZLevel( pSfrCntLoc->CreateOffsetSurf( - m_TParams.m_dDiam / 2. + EPS_SMALL, ICurve::OFF_FILLET)) ;
|
||||
if ( IsNull( pSfrCntZLevel))
|
||||
return false ;
|
||||
// calcolo tutte le curve a ZLevel e determino la regione rimossa da queste curve
|
||||
if ( ! CalcOptimalZConstCurves( pSfrCntZLevel, vSrfLoc, frSurf, vtTool, dAngDegSplit, dAngDegTol, dDepth, pCAvTlStm, vPaths)) {
|
||||
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se ho una superficie di contorno per ZConst valida
|
||||
if ( pSfrCntZConst != nullptr && pSfrCntZConst->IsValid()) {
|
||||
|
||||
// definizione regione piana di lavoro per curve ZConst
|
||||
PtrOwner<ISurfFlatRegion> pSfrZConstLoc( CloneSurfFlatRegion( pSfrCntZConst)) ;
|
||||
if ( IsNull( pSfrZConstLoc) || ! pSfrZConstLoc->IsValid() || ! pSfrZConstLoc->ToLoc( frSurf))
|
||||
return false ;
|
||||
|
||||
// recupero le curve dalla regione ZConst
|
||||
PtrOwner<ISurfFlatRegion> pSfrZConstProj( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrZConstProj) ||
|
||||
! CalcOptimalZConstCurves( pSfrZConstLoc, vSrfLoc, frSurf, vtTool, dAngDegSplit, dAngDegTol, dDepth, pCAvTlStm, vPaths, pSfrZConstProj)) {
|
||||
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// recupero le curve dalla regione Spiral
|
||||
if ( pSfrZConstProj->IsValid() && pSfrZConstProj->GetChunkCount() > 0 &&
|
||||
pSfrZigZagProjLoc->IsValid()) {
|
||||
PtrOwner<ISurfFlatRegion> pSfrZigZagProjLocClone( CloneSurfFlatRegion( pSfrZigZagProjLoc)) ;
|
||||
if ( IsNull( pSfrZigZagProjLocClone) || ! pSfrZigZagProjLocClone->IsValid())
|
||||
return false ;
|
||||
// alla superficie ZigZag tolgo la regione ZConst
|
||||
pSfrZigZagProjLoc->Subtract( *pSfrZConstProj) ;
|
||||
// nei pressi dei tratti in comune lo ZigZag deve lavorare a SideStep
|
||||
// NB. pSfrZConstProj è ingrandita di SideStep
|
||||
pSfrZigZagProjLoc->Offset( m_Params.m_dSideStep + m_TParams.m_dDiam / 2., ICurve::OFF_FILLET) ;
|
||||
// la supercicie ZigZag deve comunque essere sempre contenuta in quella definita in originale
|
||||
pSfrZigZagProjLoc->Intersect( *pSfrZigZagProjLocClone) ;
|
||||
}
|
||||
// [3°] calcolo della regione di proiezione ZigZag ---
|
||||
ISURFFRPOVECTOR vSfrZigZagProj ;
|
||||
if ( ! CalcOptimalZigZagRegion( pSfrCntZLevel, vSrfLoc, frSurf, GetToLoc( vtTool, frSurf), dDepth, dAngDegSplit, vSfrZigZagProj)) {
|
||||
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se ho una superficie di contorno per ZigZag valida
|
||||
if ( ! IsNull( pSfrZigZagProjLoc) && pSfrZigZagProjLoc->IsValid()) {
|
||||
if ( ! CalcOptimalZigZagCurves( pSfrZigZagProjLoc, frSurf, vtTool, dDepth, pCAvTlStm, vPaths)) {
|
||||
// [4°] calcolo delle curve ZigZag ---
|
||||
if ( ! vSfrZigZagProj.empty()) {
|
||||
if ( ! CalcOptimalZigZagCurves( vSfrZigZagProj, frSurf, vtTool, dDepth, pCAvTlStm, vPaths)) {
|
||||
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
|
||||
return false ;
|
||||
}
|
||||
@@ -5965,14 +6140,14 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr
|
||||
return true ;
|
||||
|
||||
// porto tutte le curve in globale
|
||||
for ( auto& path : vPaths) {
|
||||
for ( PATH& path : vPaths) {
|
||||
if ( IsNull( path.pCrvPath) || ! path.pCrvPath->IsValid())
|
||||
continue ;
|
||||
path.pCrvPath->ToGlob( frSurf) ;
|
||||
}
|
||||
|
||||
// ordino i percorsi ricavati
|
||||
if ( ! OrderOptimalPathsByZLoc( pSfrCntZConst, pSfrCntZigZag, vPaths))
|
||||
if ( ! OrderOptimalPathsByZLoc( pSfrCntExt, pSfrCnt, vPaths))
|
||||
return false ;
|
||||
|
||||
#if ENABLE_OPTIMAL_FINAL_CURVES_DEBUG
|
||||
@@ -5998,9 +6173,9 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr
|
||||
|
||||
// aggiungo i percorsi di finitura calcolati
|
||||
ICRVCOMPOPOVECTOR vCrvCompo ; vCrvCompo.resize( vPaths.size()) ;
|
||||
for ( int i = 0 ; i < int( vPaths.size()) ; ++ i)
|
||||
for ( int i = 0 ; i < ssize( vPaths) ; ++ i)
|
||||
vCrvCompo[i].Set( Release( vPaths[i].pCrvPath)) ;
|
||||
if ( ! AddFinishing( ( pSfrCntZConst == nullptr || ! pSfrCntZConst->IsValid()) ? pSfrCntZigZag : pSfrCntZConst,
|
||||
if ( ! AddFinishing( ( pSfrCntExt == nullptr || ! pSfrCntExt->IsValid()) ? pSfrCnt : pSfrCntExt,
|
||||
pCAvTlStm, frSurf, vCrvCompo, vtTool, dElev, dDepth, bSplitArcs))
|
||||
return false ;
|
||||
|
||||
|
||||
+7
-3
@@ -21,6 +21,7 @@
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EGkSurfLocal.h"
|
||||
|
||||
@@ -177,8 +178,8 @@ class SurfFinishing : public Machining
|
||||
double dFrontTriaTolerAng, double& dMaxFrontTriaRad) const ;
|
||||
bool CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SURFLOCALVECTOR& vSrfLoc,
|
||||
const Frame3d& frSurf, const Vector3d& vtTool, double dAngDegSplit,
|
||||
double dAngDegTol, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths, ISurfFlatRegion* pSfrProj) const ;
|
||||
bool CalcOptimalZigZagCurves( const ISurfFlatRegion* pSfrLoc, const Frame3d& frSurf,
|
||||
double dAngDegTol, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const ;
|
||||
bool CalcOptimalZigZagCurves( ISURFFRPOVECTOR& vSfrZigZagProj, const Frame3d& frSurf,
|
||||
const Vector3d& vtTool, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const ;
|
||||
bool GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfrLoc, const Vector3d& vtTool,
|
||||
double dDepth, double dElev, ISurfFlatRegion* pSfrSpiral, ISurfFlatRegion* pSfrZConst) const ;
|
||||
@@ -213,6 +214,9 @@ class SurfFinishing : public Machining
|
||||
bool MarchingSquares( const VECTORCOLLISIONSFR& vPntM, int nType, double dOffsTol, int nStepX, int nStepY, double dClippingAngle,
|
||||
double dLimInfClippingAng, double dLimSupClippingAng, const Vector3d& vtAxL, const Vector3d& vtMoveL, ICAvToolSurfTm* pCAvTlStm,
|
||||
ICRVCOMPOPOVECTOR& vCrvCompo) const ;
|
||||
bool AreSameSfrChunkEpsilon( const ISurfFlatRegion* pSfrChunkA, const ISurfFlatRegion* pSfrChunkB, double dMaxDist) const ;
|
||||
bool CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
|
||||
const Vector3d& vtTool, double dDepth, double dSplitAngDeg, ISURFFRPOVECTOR& vpSfrZigZagProj) const ;
|
||||
double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ;
|
||||
double GetRadiusForStartEndElevation( void) const ;
|
||||
|
||||
@@ -235,7 +239,7 @@ class SurfFinishing : public Machining
|
||||
int GetLeadOutType( void) const ;
|
||||
|
||||
private :
|
||||
SELVECTOR m_vId ; // identificativi entità geometriche da lavorare
|
||||
SELVECTOR m_vId ; // identificativi entità geometriche da lavorare
|
||||
SurfFinishingData m_Params ; // parametri lavorazione
|
||||
ToolData m_TParams ; // parametri utensile
|
||||
double m_dTHoldBase ; // posizione base del porta-utensile
|
||||
|
||||
Reference in New Issue
Block a user