diff --git a/MachMgr.h b/MachMgr.h index b7e0efd..5d3a5bb 100644 --- a/MachMgr.h +++ b/MachMgr.h @@ -538,6 +538,7 @@ class MachMgr : public IMachMgr int AddRawPart( int nSurfUpId, int nSurfDownId, double dHeight, Color cCol) ; bool SetRawPartCenter( int nRawId) ; bool ResetRawPartCenter( int nRawId) ; + bool UpdateRawOutline( int nRawId) ; // Parts bool SwapParts( bool bToRawPart) ; bool SwapRawPartParts( int nRawId, bool bToRawPart) ; diff --git a/MachMgrRawParts.cpp b/MachMgrRawParts.cpp index fa12dc5..e4e4ada 100644 --- a/MachMgrRawParts.cpp +++ b/MachMgrRawParts.cpp @@ -29,6 +29,7 @@ #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EGkSurfBezier.h" +#include "/EgtDev/Include/EGkSurfLocal.h" #include "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EXeConst.h" @@ -506,102 +507,7 @@ MachMgr::AddRawPart( int nSurfId, Color cCol) // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; // calcolo la curva di contorno - if ( bOk) { - // creo la curva - PtrOwner pCrvCompo( CreateCurveComposite()) ; - if ( IsNull( pCrvCompo)) - return GDB_ID_NULL ; - // recupero la superficie trimesh - const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nId)) ; - if ( pStm == nullptr) - return GDB_ID_NULL ; - // recupero l'ingombro della superficie in locale - BBox3d b3Srf ; - pStm->GetLocalBBox( b3Srf) ; - // ne calcolo la silhouette secondo Z+ - bool bSilh = false ; - const int NUM_TRIA_LIM = 500 ; - if ( pStm->GetTriangleCount() < NUM_TRIA_LIM) { - POLYLINEVECTOR vPL ; - if ( pStm->GetSilhouette( Z_AX, 10.0, vPL) && ! vPL.empty()) { - // cerco il contorno esterno - int nInd = - 1 ; - double dMaxArea = 0 ; - for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { - double dArea ; - if ( vPL[i].GetAreaXY( dArea) && abs( dArea) > dMaxArea) { - if ( dArea < 0) - vPL[i].Invert() ; - dMaxArea = abs( dArea) ; - nInd = i ; - } - } - // ne deduco la curva - PtrOwner pCrvSilh( CreateCurveComposite()) ; - if ( nInd >= 0 && pCrvSilh->FromPolyLine( vPL[nInd])) { - pCrvSilh->SetExtrusion( Z_AX) ; - Plane3d plProj ; - plProj.Set( b3Srf.GetMin(), Z_AX) ; - pCrvCompo.Set( GetCurveComposite( ProjectCurveOnPlane( *pCrvSilh, plProj))) ; - if ( ! IsNull( pCrvCompo)) { - pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - bSilh = true ; - } - } - } - } - else { - PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; - if ( ! IsNull( pCavParSilh)) { - Frame3d frSrf( b3Srf.GetMin()) ; - const double SILH_TOL = 1.0 ; - POLYLINEVECTOR vPL ; - if ( pCavParSilh->SetData( { pStm}, frSrf, SILH_TOL) && - pCavParSilh->GetSilhouette( 0, vPL)) { - // cerco il contorno esterno - int nInd = - 1 ; - double dMaxArea = 0 ; - for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { - double dArea ; - if ( vPL[i].GetAreaXY( dArea) && abs( dArea) > dMaxArea) { - if ( dArea < 0) - vPL[i].Invert() ; - dMaxArea = abs( dArea) ; - nInd = i ; - } - } - // ne deduco la curva - if ( nInd >= 0 && pCrvCompo->FromPolyLine( vPL[nInd])) { - pCrvCompo->SetExtrusion( Z_AX) ; - bSilh = true ; - } - } - } - } - // non riuscita, la calcolo come contorno del box - if ( ! bSilh) { - Point3d ptMin ; - double dDimX, dDimY, dDimZ ; - b3Srf.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; - PolyLine PL ; - PL.AddUPoint( 0, ptMin) ; - PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0,0)) ; - PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY,0)) ; - PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY,0)) ; - PL.AddUPoint( 4, ptMin) ; - if ( pCrvCompo->FromPolyLine( PL)) - pCrvCompo->SetExtrusion( Z_AX) ; - else - bOk = false ; - } - // inserisco la curva composita nel DB - int nCrvId = ( bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pCrvCompo)) : GDB_ID_NULL) ; - bOk = bOk && ( nCrvId != GDB_ID_NULL) ; - // assegno il nome alla curva - bOk = bOk && m_pGeomDB->SetName( nCrvId, MACH_RAW_OUTLINE) ; - // assegno il colore alla curva - bOk = bOk && m_pGeomDB->SetMaterial( nCrvId, cCol) ; - } + bOk = bOk && UpdateRawOutline( nRawId) ; // se qualcosa è andato storto, cancello tutto if ( ! bOk) { m_pGeomDB->Erase( nRawId) ; @@ -1001,6 +907,9 @@ MachMgr::RotateRawPart( int nRawId, const Vector3d& vtAx, double dAngRotDeg) LOG_ERROR( GetEMkLogger(), "Error on RotateRawPart") ; return false ; } + // se rotazione non è attorno a Z, aggiorno la curva di outline + if ( abs( dAngRotDeg) > EPS_ANG_ZERO && ! vtAx.IsZ()) + UpdateRawOutline( nRawId) ; return true ; } @@ -1139,6 +1048,122 @@ MachMgr::GetRawPartBBox( int nRawId, BBox3d& b3Raw) return m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw) ; } +//---------------------------------------------------------------------------- +bool +MachMgr::UpdateRawOutline( int nRawId) +{ + // cerco il solido del grezzo + int nSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; + if ( nSolId == GDB_ID_NULL) + return false ; + // creo la curva + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo)) + return false ; + // recupero la superficie trimesh in globale + SurfLocal pStmG( m_pGeomDB, nSolId, GLOB_FRM) ; + const ISurfTriMesh* pStm = GetSurfTriMesh( pStmG) ; + if ( pStm == nullptr) + return false ; + // recupero l'ingombro della superficie + BBox3d b3Srf ; + pStm->GetLocalBBox( b3Srf) ; + // ne calcolo la silhouette secondo Z+ globale + bool bSilh = false ; + const int NUM_TRIA_LIM = 500 ; + if ( pStm->GetTriangleCount() < NUM_TRIA_LIM) { + POLYLINEVECTOR vPL ; + if ( pStm->GetSilhouette( Z_AX, 10.0, vPL) && ! vPL.empty()) { + // cerco il contorno esterno + int nInd = - 1 ; + double dMaxArea = 0 ; + for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { + double dArea ; + if ( vPL[i].GetAreaXY( dArea) && abs( dArea) > dMaxArea) { + if ( dArea < 0) + vPL[i].Invert() ; + dMaxArea = abs( dArea) ; + nInd = i ; + } + } + // ne deduco la curva + PtrOwner pCrvSilh( CreateCurveComposite()) ; + if ( nInd >= 0 && pCrvSilh->FromPolyLine( vPL[nInd])) { + pCrvSilh->SetExtrusion( Z_AX) ; + Plane3d plProj ; + plProj.Set( b3Srf.GetMin(), Z_AX) ; + pCrvCompo.Set( GetCurveComposite( ProjectCurveOnPlane( *pCrvSilh, plProj))) ; + if ( ! IsNull( pCrvCompo)) { + pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; + bSilh = true ; + } + } + } + } + else { + PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; + if ( ! IsNull( pCavParSilh)) { + Frame3d frSrf( b3Srf.GetMin()) ; + const double SILH_TOL = 1.0 ; + POLYLINEVECTOR vPL ; + if ( pCavParSilh->SetData( { pStm}, frSrf, SILH_TOL) && + pCavParSilh->GetSilhouette( 0, vPL)) { + // cerco il contorno esterno + int nInd = - 1 ; + double dMaxArea = 0 ; + for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { + double dArea ; + if ( vPL[i].GetAreaXY( dArea) && abs( dArea) > dMaxArea) { + if ( dArea < 0) + vPL[i].Invert() ; + dMaxArea = abs( dArea) ; + nInd = i ; + } + } + // ne deduco la curva + if ( nInd >= 0 && pCrvCompo->FromPolyLine( vPL[nInd])) { + pCrvCompo->SetExtrusion( Z_AX) ; + bSilh = true ; + } + } + } + } + // non riuscita, la calcolo come contorno del box + if ( ! bSilh) { + Point3d ptMin ; + double dDimX, dDimY, dDimZ ; + b3Srf.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; + PolyLine PL ; + PL.AddUPoint( 0, ptMin) ; + PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0,0)) ; + PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY,0)) ; + PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY,0)) ; + PL.AddUPoint( 4, ptMin) ; + if ( pCrvCompo->FromPolyLine( PL)) + pCrvCompo->SetExtrusion( Z_AX) ; + else + return false ; + } + // rimuovo eventuale vecchia curva + int nOtlId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ; + m_pGeomDB->Erase( nOtlId) ; + // inserisco la curva composita nel DB + Frame3d frRaw ; + m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw) ; + pCrvCompo->ToLoc( frRaw) ; + int nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pCrvCompo)) ; + if ( nCrvId == GDB_ID_NULL) + return false ; + // assegno il nome alla curva + m_pGeomDB->SetName( nCrvId, MACH_RAW_OUTLINE) ; + // assegno il colore alla curva + Color cCol ; + if ( m_pGeomDB->GetMaterial( nSolId, cCol)) + m_pGeomDB->SetMaterial( nCrvId, cCol) ; + + return true ; +} + //--------------------------------------------------------------------------- static bool AssociateSurfs( IGeomDB* pGeomDB, int nSurfUpId, int nSurfDownId, vector>& vRawSurfs)