EgtMachKernel 1.9c3 :

- tagli di lama ora possono operare su facce di trimesh
- migliorato recupero contorni da facce.
This commit is contained in:
Dario Sassi
2018-03-14 11:00:18 +00:00
parent 1427b57169
commit 47036161c8
13 changed files with 359 additions and 496 deletions
+156
View File
@@ -469,6 +469,162 @@ Operation::GetRawGlobBox( int nPhase, const BBox3d& b3Test, double dToler, BBox3
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
bool
Operation::AdjustCurveFromSurf( ICurveComposite* pCrvCompo, int nToolDir, int nFaceUse, double dToolThick)
{
// copia della curva originale
PtrOwner<ICurveComposite> pCopy( pCrvCompo->Clone()) ;
// se richiesto contorno
if ( nFaceUse == FACE_CONT) {
// cerco l'estremo più alto e lo imposto come inizio
double dU = 0 ;
double dUmax = 0 ;
double dZmax = - INFINITO ;
Point3d ptP ;
while ( pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) {
if ( ptP.z > dZmax + EPS_SMALL) {
dZmax = ptP.z ;
dUmax = dU ;
}
dU += 1 ;
}
if ( dU != 0)
pCrvCompo->ChangeStartPoint( dUmax) ;
}
// altrimenti
else {
// ingombro
BBox3d b3Box ;
pCrvCompo->GetLocalBBox( b3Box) ;
double dMin = b3Box.GetMin().z ;
double dMax = b3Box.GetMax().z ;
if ( nFaceUse == FACE_FRONT || nFaceUse == FACE_BACK) {
dMin = b3Box.GetMin().y ;
dMax = b3Box.GetMax().y ;
}
else if ( nFaceUse == FACE_RIGHT || nFaceUse == FACE_LEFT) {
dMin = b3Box.GetMin().x ;
dMax = b3Box.GetMax().x ;
}
double dTol = min( ( dMax - dMin) / 4., 20.) ;
// cerco il punto medio delle curve più vicino all'estremo desiderato
double dRef = dMin ;
if ( nFaceUse == FACE_DOWN || nFaceUse == FACE_FRONT || nFaceUse == FACE_LEFT)
dRef = dMax ;
const ICurve* pCrv = pCrvCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
Point3d ptMid ; pCrv->GetMidPoint( ptMid) ;
switch ( nFaceUse) {
case FACE_DOWN : dRef = min( dRef, ptMid.z) ; break ;
case FACE_TOP : dRef = max( dRef, ptMid.z) ; break ;
case FACE_FRONT : dRef = min( dRef, ptMid.y) ; break ;
case FACE_BACK : dRef = max( dRef, ptMid.y) ; break ;
case FACE_LEFT : dRef = min( dRef, ptMid.x) ; break ;
case FACE_RIGHT : dRef = max( dRef, ptMid.x) ; break ;
}
pCrv = pCrvCompo->GetNextCurve() ;
}
// elimino le linee troppo discoste dal riferimento dall'inizio e poi dalla fine
pCrv = pCrvCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
Point3d ptMid ; pCrv->GetMidPoint( ptMid) ;
if ( ( nFaceUse == FACE_DOWN && ptMid.z > dRef + dTol) ||
( nFaceUse == FACE_TOP && ptMid.z < dRef - dTol) ||
( nFaceUse == FACE_FRONT && ptMid.y > dRef + dTol) ||
( nFaceUse == FACE_BACK && ptMid.y < dRef - dTol) ||
( nFaceUse == FACE_LEFT && ptMid.x > dRef + dTol) ||
( nFaceUse == FACE_RIGHT && ptMid.x < dRef - dTol)) {
ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ;
delete( pErase) ;
pCrv = pCrvCompo->GetFirstCurve() ;
}
else
break ;
}
pCrv = pCrvCompo->GetLastCurve() ;
while ( pCrv != nullptr) {
Point3d ptMid ; pCrv->GetMidPoint( ptMid) ;
if ( ( nFaceUse == FACE_DOWN && ptMid.z > dRef + dTol) ||
( nFaceUse == FACE_TOP && ptMid.z < dRef - dTol) ||
( nFaceUse == FACE_FRONT && ptMid.y > dRef + dTol) ||
( nFaceUse == FACE_BACK && ptMid.y < dRef - dTol) ||
( nFaceUse == FACE_LEFT && ptMid.x > dRef + dTol) ||
( nFaceUse == FACE_RIGHT && ptMid.x < dRef - dTol)) {
ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ;
delete( pErase) ;
pCrv = pCrvCompo->GetLastCurve() ;
}
else
break ;
}
}
// determino il versore estrusione (utensile)
if ( nToolDir == TOOL_ORTHO)
pCrvCompo->SetThickness( 0) ;
else if ( nToolDir == TOOL_ORTUP) {
Vector3d vtN ;
pCrvCompo->GetExtrusion( vtN) ;
if ( vtN.z < - sin( 2 * DEGTORAD)) {
// pCrvCompo->Invert() ;
pCrvCompo->Translate( vtN * dToolThick) ;
pCrvCompo->SetExtrusion( - vtN) ;
}
pCrvCompo->SetThickness( 0) ;
}
else { // nToolDir == TOOL_PARAL
// sistemo versore
Vector3d vtN ;
pCrvCompo->GetExtrusion( vtN) ;
Point3d ptStart, ptEnd ;
pCrvCompo->GetStartPoint( ptStart) ;
pCrvCompo->GetEndPoint( ptEnd) ;
Vector3d vtT = ptEnd - ptStart ;
Vector3d vtExtr = vtN ^ vtT ;
if ( ! vtExtr.Normalize())
return false ;
pCrvCompo->SetExtrusion( vtExtr) ;
// elimino eventuali parti iniziali e/o finali dirette circa come il versore
const double MAX_ALL_COS = cos( 25 * DEGTORAD) ;
const ICurve* pCrv = pCrvCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
Vector3d vtDir ; pCrv->GetStartDir( vtDir) ;
if ( abs( vtDir * vtExtr) > MAX_ALL_COS) {
ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ;
delete( pErase) ;
pCrv = pCrvCompo->GetFirstCurve() ;
}
else if ( pCrvCompo->IsClosed()) {
pCrvCompo->ChangeStartPoint( 1) ;
pCrv = pCrvCompo->GetFirstCurve() ;
}
else
break ;
}
pCrv = pCrvCompo->GetLastCurve() ;
while ( pCrv != nullptr) {
Vector3d vtDir ; pCrv->GetStartDir( vtDir) ;
if ( abs( vtDir * vtExtr) > MAX_ALL_COS) {
ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ;
delete( pErase) ;
pCrv = pCrvCompo->GetLastCurve() ;
}
else
break ;
}
// determino lo spessore misurato lungo la direzione
if ( ! IsNull( pCopy)) {
Frame3d frOcs ; frOcs.Set( ORIG, vtExtr) ;
Frame3d frExtr ; frExtr.ToLoc( frOcs) ;
BBox3d b3Extr ; pCopy->GetBBox( frExtr, b3Extr) ;
if ( ! b3Extr.IsEmpty())
pCrvCompo->SetThickness( b3Extr.GetMax().z - b3Extr.GetMin().z) ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Operation::ApproxWithArcsIfUseful( ICurveComposite* pCompo)