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:
Riccardo Elitropi
2026-05-21 12:01:27 +02:00
parent d0bbc52253
commit ae5a7b8064
3 changed files with 664 additions and 473 deletions
+220 -208
View File
@@ -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