From cc78817ed7b25c430d9136256f30d09c27ffabf6 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 11 Jan 2016 14:33:38 +0000 Subject: [PATCH] EgtExecutor 1.6l7 : - modifiche e nuove funzione per nesting. --- EXE_Const.h | 1 + EXE_GdbModifySurf.cpp | 5 +- EXE_NstPartNesting.cpp | 191 ++++++++++++++++++++++++++++++++++------- EgtExecutor.rc | Bin 11694 -> 11694 bytes 4 files changed, 166 insertions(+), 31 deletions(-) diff --git a/EXE_Const.h b/EXE_Const.h index c628fa6..1a5a80a 100644 --- a/EXE_Const.h +++ b/EXE_Const.h @@ -23,3 +23,4 @@ static std::string NST_PART_REG = "Region" ; static std::string NST_EXT_LAYER = "OutLoop" ; static std::string NST_IN_LAYER = "InLoop" ; static std::string NST_ON_LAYER = "OnPath" ; +static std::string NST_SHEET_OUTREG = "SheetOut" ; \ No newline at end of file diff --git a/EXE_GdbModifySurf.cpp b/EXE_GdbModifySurf.cpp index 5a3c198..aa7809e 100644 --- a/EXE_GdbModifySurf.cpp +++ b/EXE_GdbModifySurf.cpp @@ -22,6 +22,7 @@ #include "/EgtDev/Include/EgkCurveComposite.h" #include "/EgtDev/Include/EgkSurfFlatRegion.h" #include "/EgtDev/Include/EgkSurfTriMesh.h" +#include "/EgtDev/Include/EgkSimpleCDSurfFrMove.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EgtPointerOwner.h" @@ -397,7 +398,7 @@ ExeSurfFrMoveSimpleNoCollision( int nId1, int nId2, const Vector3d& vtDir, doubl // porto in locale alla prima superficie il versore di movimento Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf1) ; // calcolo massima lunghezza di traslazione della prima regione senza semplice collisione con la seconda - return ( bOk && pSfr1->TranslateSimpleNoCollision( *pSfr2L, vtDirL, dLen)) ; + return ( bOk && SimpleCDSurfFrMove( *pSfr1, *pSfr2L).Translate( vtDirL, dLen)) ; } //---------------------------------------------------------------------------- @@ -430,7 +431,7 @@ ExeSurfFrRotateSimpleNoCollision( int nId1, int nId2, const Point3d& ptCen, doub // porto in locale alla prima superficie il versore di movimento Point3d ptCenL = GetPointLocal( pGeomDB, ptCen, nRefType, frSurf1) ; // calcolo massimo angolo di rotazione della prima regione senza semplice collisione con la seconda - return ( bOk && pSfr1->RotateSimpleNoCollision( *pSfr2L, ptCenL, dAngDeg)) ; + return ( bOk && SimpleCDSurfFrMove( *pSfr1, *pSfr2L).Rotate(ptCenL, dAngDeg)) ; } //---------------------------------------------------------------------------- diff --git a/EXE_NstPartNesting.cpp b/EXE_NstPartNesting.cpp index 8091da7..e29ba9e 100644 --- a/EXE_NstPartNesting.cpp +++ b/EXE_NstPartNesting.cpp @@ -20,6 +20,8 @@ #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkSfrCreate.h" +#include "/EgtDev/Include/EGkSimpleCDSurfFrMove.h" +#include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EMkMachiningGeoConst.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include @@ -68,24 +70,25 @@ GetFlatPartCutRegions( IGeomDB* pGeomDB, int nId, bool bReduced, INTVECTOR& vCrI //---------------------------------------------------------------------------- static int -CreateOutBoxRegion( IGeomDB* pGeomDB, int nParentId, double dXmin, double dYmin, double dXmax, double dYmax) +CreateOutBoxRegion( IGeomDB* pGeomDB, int nParentId, + double dXmin, double dYmin, double dXmax, double dYmax, double dZ) { // creo polilinea attorno al box (avvolta a serpente) const double SPESS = 100 ; const double DELTA = 1 ; PolyLine PL ; - PL.AddUPoint( 0, Point3d( dXmin, dYmin, 0)) ; - PL.AddUPoint( 1, Point3d( dXmin, dYmax, 0)) ; - PL.AddUPoint( 2, Point3d( dXmax, dYmax, 0)) ; - PL.AddUPoint( 3, Point3d( dXmax, dYmin + DELTA + 2 * EPS_SMALL, 0)) ; - PL.AddUPoint( 4, Point3d( dXmax + SPESS, dYmin + DELTA + 2 * EPS_SMALL, 0)) ; - PL.AddUPoint( 5, Point3d( dXmax + SPESS, dYmax + SPESS, 0)) ; - PL.AddUPoint( 6, Point3d( dXmin - SPESS, dYmax + SPESS, 0)) ; - PL.AddUPoint( 7, Point3d( dXmin - SPESS, dYmin - SPESS, 0)) ; - PL.AddUPoint( 8, Point3d( dXmax + SPESS, dYmin - SPESS, 0)) ; - PL.AddUPoint( 9, Point3d( dXmax + SPESS, dYmin + DELTA, 0)) ; - PL.AddUPoint( 10, Point3d( dXmax, dYmin + DELTA, 0)) ; - PL.AddUPoint( 11, Point3d( dXmax, dYmin, 0)) ; + PL.AddUPoint( 0, Point3d( dXmin, dYmin, dZ)) ; + PL.AddUPoint( 1, Point3d( dXmin, dYmax, dZ)) ; + PL.AddUPoint( 2, Point3d( dXmax, dYmax, dZ)) ; + PL.AddUPoint( 3, Point3d( dXmax, dYmin + DELTA + 2 * EPS_SMALL, dZ)) ; + PL.AddUPoint( 4, Point3d( dXmax + SPESS, dYmin + DELTA + 2 * EPS_SMALL, dZ)) ; + PL.AddUPoint( 5, Point3d( dXmax + SPESS, dYmax + SPESS, dZ)) ; + PL.AddUPoint( 6, Point3d( dXmin - SPESS, dYmax + SPESS, dZ)) ; + PL.AddUPoint( 7, Point3d( dXmin - SPESS, dYmin - SPESS, dZ)) ; + PL.AddUPoint( 8, Point3d( dXmax + SPESS, dYmin - SPESS, dZ)) ; + PL.AddUPoint( 9, Point3d( dXmax + SPESS, dYmin + DELTA, dZ)) ; + PL.AddUPoint( 10, Point3d( dXmax, dYmin + DELTA, dZ)) ; + PL.AddUPoint( 11, Point3d( dXmax, dYmin, dZ)) ; PL.Close() ; // la converto in curva composita PtrOwner pCompo( CreateCurveComposite()) ; @@ -97,12 +100,19 @@ CreateOutBoxRegion( IGeomDB* pGeomDB, int nParentId, double dXmin, double dYmin, ISurfFlatRegion* pSfr = SfrCntr.GetSurf() ; if ( pSfr == nullptr) return GDB_ID_NULL ; + // recupero il riferimento del gruppo di inserimento + Frame3d frLoc ; + if ( ! pGeomDB->GetGroupGlobFrame( nParentId, frLoc)) + return GDB_ID_NULL ; + // porto la regione nel riferimento + pSfr->ToLoc( frLoc) ; // inserisco la superficie nel DB int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSfr) ; if ( nId == GDB_ID_NULL) return GDB_ID_NULL ; - // la dichiaro temporanea e invisibile - pGeomDB->SetLevel( nId, GDB_LV_TEMP) ; + // assegno nome e la dichiaro temporanea e invisibile + pGeomDB->SetName( nId, NST_SHEET_OUTREG) ; + pGeomDB->SetLevel( nId, GDB_LV_SYSTEM) ; pGeomDB->SetMaterial( nId, INVISIBLE) ; return nId ; } @@ -370,6 +380,77 @@ ExePackPartCluster( const INTVECTOR& vIds, bool bReducedCut, } } +//---------------------------------------------------------------------------- +static SCollInfo s_scInfo ; + +//---------------------------------------------------------------------------- +static double +UpdateCollId( double dLen, double dPrevLen, int nId1, int nId2, SCollInfo scInfoCurr) +{ + if ( abs( dLen - dPrevLen) < EPS_SMALL) { + if ( scInfoCurr.nType == SCI_PNT_LINE || scInfoCurr.nType == SCI_LINE_LINE) { + s_scInfo = scInfoCurr ; + s_scInfo.nIdM = nId1 ; + s_scInfo.nIdF = nId2 ; + } + return dPrevLen ; + } + else if ( dLen < dPrevLen) { + s_scInfo = scInfoCurr ; + s_scInfo.nIdM = nId1 ; + s_scInfo.nIdF = nId2 ; + return dLen ; + } + else + return dPrevLen ; +} + +//---------------------------------------------------------------------------- +static bool +MySurfFrMoveSimpleNoCollision( int nId1, int nId2, const Vector3d& vtDir, double& dLen, SCollInfo& scInfo) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + // recupero la prima superficie FlatRegion + ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ; + bool bOk = ( pSfr1 != nullptr) ; + // recupero il riferimento della superficie + Frame3d frSurf1 ; + bOk = bOk && pGeomDB->GetGlobFrame( nId1, frSurf1) ; + // recupero la seconda superficie FlatRegion + const ISurfFlatRegion* pSfr2 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId2)) ; + bOk = bOk && ( pSfr2 != nullptr) ; + // recupero il riferimento della superficie + Frame3d frSurf2 ; + bOk = bOk && pGeomDB->GetGlobFrame( nId2, frSurf2) ; + // se riferimenti diversi, porto una copia della seconda nel riferimento della prima + const ISurfFlatRegion* pSfr2L = pSfr2 ; + PtrOwnerpTmp ; + if ( ! AreSameFrame( frSurf1, frSurf2)) { + pTmp.Set( CloneSurfFlatRegion( pSfr2)) ; + bOk = bOk && ! IsNull( pTmp) ; + bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ; + pSfr2L = Get( pTmp) ; + } + // porto in locale alla prima superficie il versore di movimento + Vector3d vtDirL = vtDir ; + vtDirL.ToLoc( frSurf1) ; + // calcolo massima lunghezza di traslazione della prima regione senza semplice collisione con la seconda + SimpleCDSurfFrMove ScdSfrMove( *pSfr1, *pSfr2L) ; + bOk = bOk && ScdSfrMove.Translate( vtDirL, dLen) ; + if ( bOk) { + scInfo = ScdSfrMove.GetSCollInfo() ; + if ( scInfo.nType != SCI_NONE) { + scInfo.ptP1.ToGlob( frSurf1) ; + scInfo.vtDirM.ToGlob( frSurf1) ; + scInfo.vtDirF.ToGlob( frSurf1) ; + } + if ( scInfo.nType == SCI_LINE_LINE) + scInfo.ptP2.ToGlob( frSurf1) ; + } + return bOk ; +} + //---------------------------------------------------------------------------- static bool MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove, @@ -382,6 +463,9 @@ MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove, dYmax < dYmin + EPS_SMALL) return false ; + // Reset info di collisione + s_scInfo.nType = SCI_NONE ; + // Vettore movimento nel piano XY globale Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; vtMove = V_NULL ; @@ -443,14 +527,17 @@ MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove, nId2 = ( bInRoot ? ExeGetNextPart( nId2, true) : ExeGetNextGroup( nId2)) ; } - // Creo SurfFlatRegion che delimita la regione valida - int nBoxId = CreateOutBoxRegion( pGeomDB, GDB_ID_ROOT, dXmin, dYmin, dXmax, dYmax) ; + // Se non esiste, creo SurfFlatRegion che delimita la regione valida + int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ; + if ( nBoxId == GDB_ID_NULL) + nBoxId = CreateOutBoxRegion( pGeomDB, nGroupId, dXmin, dYmin, dXmax, dYmax, b3Cluster.GetMin().z) ; if ( nBoxId == GDB_ID_NULL) return false ; // Verifico movimento dei pezzi del cluster rispetto agli altri pezzi bool bOk = true ; double dLen = vtMoveXY.Len() ; + double dPrevLen = dLen ; Vector3d vtDir = ( dLen > EPS_SMALL ? vtMoveXY / dLen : V_NULL) ; for ( auto nTrueId : vTrueIds) { // recupero regione del pezzo @@ -459,15 +546,20 @@ MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove, bOk = false ; break ; } + // info di collisione correnti + SCollInfo scInfoCurr ; // la confronto con il box - ExeSurfFrMoveSimpleNoCollision( nRegId, nBoxId, vtDir, dLen, RTY_GLOB) ; + MySurfFrMoveSimpleNoCollision( nRegId, nBoxId, vtDir, dLen, scInfoCurr) ; + dPrevLen = UpdateCollId( dLen, dPrevLen, nRegId, nBoxId, scInfoCurr) ; // la confronto con le regioni degli altri pezzi for ( int nOthRegId : vOthReg) { - ExeSurfFrMoveSimpleNoCollision( nRegId, nOthRegId, vtDir, dLen, RTY_GLOB) ; + MySurfFrMoveSimpleNoCollision( nRegId, nOthRegId, vtDir, dLen, scInfoCurr) ; + dPrevLen = UpdateCollId( dLen, dPrevLen, nRegId, nOthRegId, scInfoCurr) ; } // e con le regioni dei tagli degli altri pezzi for ( int nOthCutRegId : vOthCutReg) { - ExeSurfFrMoveSimpleNoCollision( nRegId, nOthCutRegId, vtDir, dLen, RTY_GLOB) ; + MySurfFrMoveSimpleNoCollision( nRegId, nOthCutRegId, vtDir, dLen, scInfoCurr) ; + dPrevLen = UpdateCollId( dLen, dPrevLen, nRegId, nOthCutRegId, scInfoCurr) ; } // recupero regioni di lavorazione del pezzo INTVECTOR vCrId ; @@ -478,18 +570,37 @@ MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove, // le confronto con le regioni degli altri pezzi for ( int nCrId : vCrId) { for ( int nOthRegId : vOthReg) { - ExeSurfFrMoveSimpleNoCollision( nCrId, nOthRegId, vtDir, dLen, RTY_GLOB) ; + MySurfFrMoveSimpleNoCollision( nCrId, nOthRegId, vtDir, dLen, scInfoCurr) ; + dPrevLen = UpdateCollId( dLen, dPrevLen, nCrId, nOthRegId, scInfoCurr) ; } } } - // Elimino la regione aggiunta per il Box - pGeomDB->Erase( nBoxId) ; - // Se errore if ( ! bOk) return false ; + // Log provvisorio + if ( s_scInfo.nType != SCI_NONE) { + string sOut = "Id1=" + ToString( s_scInfo.nIdM) + " Id2=" + ToString( s_scInfo.nIdF) + " Info type=" ; + switch ( s_scInfo.nType) { + case SCI_NONE : sOut += "NONE" ; break ; + case SCI_PNT_PNT : sOut += "PNT_PNT" ; break ; + case SCI_PNT_LINE : sOut += "PNT_LINE" ; break ; + case SCI_LINE_PNT : sOut += "LINE_PNT" ; break ; + case SCI_LINE_LINE : sOut += "LINE_LINE" ; break ; + } + sOut += " Crv1=" + ToString( s_scInfo.nCrvM) + " Crv2=" + ToString( s_scInfo.nCrvF) ; + sOut += " ptA=(" + ToString( s_scInfo.ptP1) + ")" ; + if ( s_scInfo.nType == SCI_LINE_LINE) + sOut += " ptB=(" + ToString( s_scInfo.ptP2) + ")" ; + if ( s_scInfo.nType == SCI_LINE_PNT || s_scInfo.nType == SCI_LINE_LINE) + sOut += " Dir1=(" + ToString( s_scInfo.vtDirM) + ")" ; + if ( s_scInfo.nType == SCI_PNT_LINE || s_scInfo.nType == SCI_LINE_LINE) + sOut += " Dir2=(" + ToString( s_scInfo.vtDirF) + ")" ; + LOG_INFO( GetLogger(), sOut.c_str()) ; + } + // Se movimento risultante nullo, non faccio alcunché vtMoveXY = vtDir * dLen ; if ( vtMoveXY.IsSmall()) @@ -499,8 +610,8 @@ MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove, for ( auto nTrueId : vTrueIds) pGeomDB->TranslateGlob( nTrueId, vtMoveXY) ; ExeSetModified() ; - vtMove = vtMoveXY ; + return true ; } @@ -549,6 +660,26 @@ ExeMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove, } } +//---------------------------------------------------------------------------- +bool +ExeGetObstacleTangent( Vector3d& vtTang) +{ + if ( s_scInfo.nType != SCI_PNT_LINE && s_scInfo.nType != SCI_LINE_LINE) + return false ; + vtTang = s_scInfo.vtDirF ; + return vtTang.Normalize() ; +} + +//---------------------------------------------------------------------------- +bool +ExeGetMovingTangent( Vector3d& vtTang) +{ + if ( s_scInfo.nType != SCI_LINE_PNT && s_scInfo.nType != SCI_LINE_LINE) + return false ; + vtTang = s_scInfo.vtDirM ; + return vtTang.Normalize() ; +} + //---------------------------------------------------------------------------- bool ExeRotatePartCluster( const INTVECTOR& vIds, bool bReducedCut, const Point3d& ptCen, double& dRotAngDeg, @@ -561,6 +692,9 @@ ExeRotatePartCluster( const INTVECTOR& vIds, bool bReducedCut, const Point3d& pt dYmax < dYmin + EPS_SMALL) return false ; + // Reset info di collisione + s_scInfo.nType = SCI_NONE ; + // Rotazione nel piano XY globale // Box della regione di interesse @@ -619,7 +753,9 @@ ExeRotatePartCluster( const INTVECTOR& vIds, bool bReducedCut, const Point3d& pt } // Creo SurfFlatRegion che delimita la regione valida - int nBoxId = CreateOutBoxRegion( pGeomDB, GDB_ID_ROOT, dXmin, dYmin, dXmax, dYmax) ; + int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ; + if ( nBoxId == GDB_ID_NULL) + nBoxId = CreateOutBoxRegion( pGeomDB, nGroupId, dXmin, dYmin, dXmax, dYmax, b3Cluster.GetMin().z) ; if ( nBoxId == GDB_ID_NULL) return false ; @@ -657,9 +793,6 @@ ExeRotatePartCluster( const INTVECTOR& vIds, bool bReducedCut, const Point3d& pt } } - // Elimino la regione aggiunta per il Box - pGeomDB->Erase( nBoxId) ; - // Se errore if ( ! bOk) return false ; diff --git a/EgtExecutor.rc b/EgtExecutor.rc index 3ae2b1f748e88f1a409d3eacb841f1ee3614c751..544724e695707b04f48a1f9ffd654f267059e2b0 100644 GIT binary patch delta 97 zcmZ1%y)JsgA2vqw%@@V4Gflq2na5~8Ignd-a{*Tk3sCf++-0W82LxfF21;&>n->Y| cF@rU@0x76sKgP|Iq`|@mWB>pF delta 105 zcmZ1%y)JsgA2vp_%@@V4Gflq2nKwB}L}GFQr`YBKt{N7g_(8eLOp^}?BE$`p+!!}6 e64qk|YjR~q(%{Fqd6G0(;-H)(Lc&0)jvD~(JR=+c