diff --git a/MachineLuaCL.cpp b/MachineLuaCL.cpp index 3ad83b0..5130076 100644 --- a/MachineLuaCL.cpp +++ b/MachineLuaCL.cpp @@ -22,7 +22,9 @@ #include "/EgtDev/Include/EGkGeoVector3d.h" #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveArc.h" +#include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkIntersLineCylinder.h" +#include "/EgtDev/Include/EGkOffsetCurve3d.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkLuaAux.h" #include "/EgtDev/Include/EGkStringUtils3d.h" @@ -601,36 +603,6 @@ Machine::LuaEmtGetBackAuxDir( lua_State* L) return 1 ; } -struct Cyl { - Cyl( void): frCyl( GLOB_FRM), dH( 0.), dRad( 0.) {;} ; - Cyl( const Frame3d& _frCyl, double _dH, double _dRad, double _dLinTol) : - frCyl( _frCyl), dH( _dH), dRad( _dRad) { ;} - Cyl( const Point3d& _ptBase, const Vector3d& vtZ, double _dH, double _dRad, double _dLinTol) : - dH( _dH), dRad( _dRad){ - frCyl.Set( _ptBase, vtZ); } -public : - Frame3d frCyl ; -public: - double dH ; - double dRad ; -}; - -typedef vector OFFSETCYLVECT ; - -//---------------------------------------------------------------------------- -bool -IsPointInsideCylinder( const Point3d& ptTest, const Cyl& offCyl, double dLinTol) -{ - Point3d ptTestLoc = ptTest ; ptTestLoc.ToLoc( offCyl.frCyl) ; - if ( ptTestLoc.z > offCyl.dH || ptTestLoc.z < 0) - return false ; - double dDist = ptTestLoc.x * ptTestLoc.x + ptTestLoc.y * ptTestLoc.y ; - double dRadSq = ( offCyl.dRad - dLinTol) * ( offCyl.dRad - dLinTol) ; - if ( dDist > dRadSq) - return false ; - return true ; -} - //---------------------------------------------------------------------------- int Machine::LuaEmtAdjustConcavePartsInPath( lua_State* L) @@ -647,218 +619,96 @@ Machine::LuaEmtAdjustConcavePartsInPath( lua_State* L) IGeomDB* pGeomDB = m_pMchLua->m_pGeomDB ; int nId = pGeomDB->GetFirstInGroup( nPathId) ; int nIdCrvAux = pGeomDB->GetFirstInGroup( nAuxPathId) ; - const ICurve* pCrvAux = GetCurve( pGeomDB->GetGeoObj(nIdCrvAux)) ; - const double dLinTol = 10 * EPS_SMALL ; - -#if DRAWCYL - int nParent = pGeomDB->GetParentId( nPathId) ; - int nTempLay = pGeomDB->AddGroup( GDB_ID_NULL, nParent, GLOB_FRM) ; -#endif - + const ICurveComposite* pCrvAux = GetCurveComposite( pGeomDB->GetGeoObj(nIdCrvAux)) ; + if ( pCrvAux == nullptr) + return GDB_ID_NULL ; + int nFirstCrvOffset = nId ; + OFFSETSEGVEC vOffsetCrvs ; while ( nId != GDB_ID_NULL) { if ( pGeomDB->GetGeoType( nId) == CRV_LINE) { - int nFlag = 0 ; pGeomDB->GetInfo( nId, "Flg2", nFlag) ; - if ( nFlag == 1) { - // scorro i prossimi finchè trovo la fine della zona concava - INTINTVECTOR vLines ; - while ( nFlag == 1 && nId != GDB_ID_NULL) { - nId = pGeomDB->GetNext( nId) ; - if ( nId != GDB_ID_NULL && pGeomDB->GetGeoType( nId) == CRV_LINE) { - int nDerivedFromId = GDB_ID_NULL ; - if ( pGeomDB->GetInfo( nId, "DerivFrom", nDerivedFromId)) { - pGeomDB->GetInfo( nId, "Flg2", nFlag) ; - vLines.emplace_back( nId, nDerivedFromId) ; - } - } - } - OFFSETCYLVECT vCyl ; - // creo un cilindro della dimensione del raggio - for ( int i = 0 ; i < ssize( vLines) ; ++i) { - #if COLOR5AX - pGeomDB->SetMaterial( vLines[i].first, GREEN) ; - #endif - const IGeoVector3d* pGV = GetGeoVector3d( pGeomDB->GetGeoObj( vLines[i].second)) ; - if ( pGV == nullptr) - return false ; - Point3d ptBase = pGV->GetBase() ; - double dPar = 0 ; - if ( ! pCrvAux->GetParamAtPoint( ptBase, dPar)) - return false ; + const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ; + int nParent = -1 ; + int nDerivFrom = - 1 ; + pGeomDB->GetInfo( nId, "DerivFrom", nDerivFrom) ; + const IGeoVector3d* pGV = GetGeoVector3d( pGeomDB->GetGeoObj( nDerivFrom)) ; + if ( pGV != nullptr) { + Point3d ptBase = pGV->GetBase() ; + double dPar = 0 ; + if ( pCrvAux->GetParamAtPoint( ptBase, dPar)) + nParent = int( round( dPar)) - 1 ; + } + int nFlagAng = 0 ; + pGeomDB->GetInfo( nId, "FlgAng", nFlagAng) ; + vOffsetCrvs.emplace_back( pCrv->Clone(), nFlagAng, nParent) ; + } + nId = pGeomDB->GetNext( nId) ; + } + EDITCRVINFOVEC vEditInfo ; + if ( ! CalcAdjustConcavePartsInPath( pCrvAux, vOffsetCrvs, dRad, vEditInfo)) + return GDB_ID_NULL ; - dPar = round( dPar) ; - if ( dPar > 0) { - Point3d ptStart, ptEnd ; - Vector3d vtHeight ; - pCrvAux->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptEnd, &vtHeight) ; - pCrvAux->GetPointD1D2( dPar - 1, ICurve::FROM_MINUS, ptStart) ; - vtHeight = ptEnd - ptStart ; - double dHeight = vtHeight.Len() ; - // questa altezza dovrebbe coincidere con quella precedentemente calcolata come direzione della linea - vtHeight.Normalize() ; - vCyl.emplace_back( ptStart, vtHeight, dHeight, dRad, dLinTol) ; - #if DRAWCYL - pGeomDB->SetGridFrame( vCyl.back().frCyl) ; - int nIdCrv = ExeCreateCircle( nTempLay, ORIG, dRad, GDB_ID_GRID) ; - ExeCreateSurfTmByExtrusion( nTempLay, {nIdCrv}, Z_AX * dHeight, 0.005, GDB_ID_GRID) ; - pGeomDB->Erase( nIdCrv) ; - #endif - } - } - #if DRAWCYL - pGeomDB->SetGridFrame( GLOB_FRM) ; - #endif - - // controllo l'end di ogni linea per verificare se sta nel cilindro definito da uno degli altri tratti - // controllo tutto i punti - bool bErasedSomePart = false ; - bool bCheckStart = false ; - INTINTVECTOR vInters ; - for ( int i = 0 ; i < ssize( vLines) ; ++i) { - Point3d ptStart, ptEnd ; - const ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( vLines[i].first)) ; - if ( pCL == nullptr) - return false ; - pCL->GetEndPoint( ptEnd) ; - pCL->GetStartPoint( ptStart) ; - // se stanno in uno dei cilindri degli altri tratti della zona concava - bool bToErase = false ; - for ( int j = 0 ; j < ssize( vCyl) ; ++j) { - if ( i == j) - continue ; - bToErase = IsPointInsideCylinder( ptEnd, vCyl[j], dLinTol) ; - bool bStartInsideCyl = false ; - if ( bCheckStart && ! bToErase) { - bStartInsideCyl = IsPointInsideCylinder( ptStart, vCyl[j], dLinTol) ; - bToErase = bToErase || bStartInsideCyl ; - } - if ( bToErase) { - bErasedSomePart = true ; - if ( ! bStartInsideCyl) - bCheckStart = true ; - // se avevo un'interruzione nella zona da modificare, la colmo - if ( ! vInters.empty() && vInters.back().first != vLines[i-1].first) { - // aggiungo tutti i precedenti che mancano - int nLastAdded = i - ( vLines[i].first - vInters.back().first) ; - for ( int h = nLastAdded + 1 ; h < i ; ++h) - vInters.emplace_back( vLines[h].first, h) ; - } - vInters.emplace_back( vLines[i].first,i) ; - if ( ! bStartInsideCyl && i < ssize( vLines) - 1) { - vInters.emplace_back( vLines[i+1].first,i+1) ; - ++i ; - } - break ; - } - } - if ( ! bToErase) - bCheckStart = false ; - } - if ( bErasedSomePart) { - // calcolo le intersezioni effettive del primo e ultimo tratto cancellati con i cilindri che li hanno cancellati - // controllo che effettivamente tutti i tratti cancellati siano consecutivi - for ( int i = 1 ; i < ssize( vInters) ; ++i) { - if ( vInters[i].first != vInters[i-1].first + 1) - return false ; - } - for ( int i = 0 ; i < ssize( vInters) ; ++i) { - #if COLOR5AX - pGeomDB->SetMaterial( vInters[i].first, YELLOW) ; - #endif - // cancello i tratti intermedi - if ( i > 0 && i < ssize( vInters) - 1) { - pGeomDB->Erase( vInters[i].first) ; - continue ; - } - - // per il primo e ultimo controllo le intersezioni con tutti i cilindri - ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( vInters[i].first)) ; - Point3d ptStart = pCL->GetStart() ; - Vector3d vtStart ; pCL->GetStartDir( vtStart) ; - double dLen ; pCL->GetLength( dLen) ; - double dUTrim = ( i == 0 ? INFINITO : 0) ; - Point3d ptTrim = P_INVALID ; - for ( int j = 0 ; j < ssize( vCyl) ; ++j) { - if ( vInters[i].second == j) - continue ; - Point3d ptInt1 = P_INVALID, ptInt2 = P_INVALID ; - double dU1, dU2 ; - Vector3d vtN1, vtN2 ; - if ( IntersLineCyl( ptStart, vtStart * dLen, vCyl[j].frCyl, vCyl[j].dH, vCyl[j].dRad, dU1, ptInt1, vtN1, dU2, ptInt2, vtN2)) { - bool bUpdate = ( i == 0 ? dU1 < dUTrim : dU1 > dUTrim) ; - bUpdate = bUpdate && ptInt1.IsValid() && dU1 > 0 && dU1 < 1 ; - bUpdate = bUpdate && vtN1 * vtStart < 0 ; - if ( bUpdate) { - dUTrim = dU1 ; - ptTrim = ptInt1 ; - } - bUpdate = ( i == 0 ? dU2 < dUTrim : dU2 > dUTrim) ; - bUpdate = bUpdate && ptInt2.IsValid() && dU2 > 0 && dU2 < 1 ; - bUpdate = bUpdate && vtN2 * vtStart > 0 ; - if ( bUpdate) { - dUTrim = dU2 ; - ptTrim = ptInt2 ; - } - } - } - if ( ptTrim.IsValid()) { - if ( i == 0) { - #if COLOR5AX - pGeomDB->SetMaterial( vInters[i].first, RED) ; - #endif - pCL->ModifyEnd( ptTrim) ; - double dNewLen ; pCL->GetLength( dNewLen) ; - if ( dNewLen < 0.1) { - int nPrev = pGeomDB->GetPrev( vInters[0].first) ; - pGeomDB->Erase( vInters[0].first) ; - vInters[0].first = nPrev ; - #if COLOR5AX - pGeomDB->SetMaterial( nPrev, RED) ; - #endif - ICurveLine* pCLPrev = GetCurveLine( pGeomDB->GetGeoObj( nPrev)) ; - pCLPrev->ModifyEnd( ptTrim) ; - } - CamData* camData = GetCamData( pGeomDB->GetUserObj( vInters[0].first)) ; - camData->SetEndPoint( ptTrim) ; - } - else { - #if COLOR5AX - pGeomDB->SetMaterial( vInters[i].first, RED) ; - #endif - pCL->ModifyStart( ptTrim) ; - double dNewLen ; pCL->GetLength( dNewLen) ; - if ( dNewLen < 0.1) { - int nNext = pGeomDB->GetNext( vInters[i].first) ; - pGeomDB->Erase( vInters[i].first) ; - vInters[i].first = nNext ; - #if COLOR5AX - pGeomDB->SetMaterial( nNext, RED) ; - #endif - ICurveLine* pCLNext = GetCurveLine( pGeomDB->GetGeoObj( nNext)) ; - pCLNext->ModifyStart( ptTrim) ; - } - } - } - } - // giunto questi due punti - ICurveLine* pCLprev = GetCurveLine( pGeomDB->GetGeoObj( vInters[0].first)) ; - Point3d ptIni = pCLprev->GetEnd() ; - ICurveLine* pCLnext = GetCurveLine( pGeomDB->GetGeoObj( vInters.back().first)) ; - Point3d ptFin = pCLnext->GetStart() ; - const CamData* camDataPrev = GetCamData( pGeomDB->GetUserObj( vInters[0].first)) ; - const CamData* camDataNext = GetCamData( pGeomDB->GetUserObj( vInters.back().first)) ; - Vector3d vtTool = Media( camDataPrev->GetToolDir(), camDataNext->GetToolDir()) ; - Vector3d vtCorr = Media( camDataPrev->GetCorrDir(), camDataNext->GetCorrDir()) ; - Vector3d vtAux = Media( camDataPrev->GetAuxDir(), camDataNext->GetAuxDir()) ; - double dFeed = camDataPrev->GetFeed() ; - int nFlag = camDataPrev->GetFlag() ; - int nFlag2 = camDataPrev->GetFlag2() ; - bool bToolShow = camDataPrev->GetToolShow() ; - AddLinearMove( ptIni, ptFin, pGeomDB, nPathId, vtTool, vtCorr, vtAux, dFeed, nFlag, nFlag2, bToolShow, vInters[0].first) ; - } - nId = vLines.back().first ; + // applico le modifiche calcolate + for ( int i = 0 ; i < ssize( vEditInfo) ; ++i) { + if ( vEditInfo[i].nFlag == EditCrvInfo::NOEDIT) + continue ; + else if ( vEditInfo[i].nFlag == EditCrvInfo::DEL) { + pGeomDB->Erase( nFirstCrvOffset + i) ; + } + else if ( vEditInfo[i].nFlag == EditCrvInfo::EDIT) { + if ( vEditInfo[i].ptStart.IsValid()) { + ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( nFirstCrvOffset + i)) ; + pCL->ModifyStart( vEditInfo[i].ptStart) ; + } + if ( vEditInfo[i].ptEnd.IsValid()) { + ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( nFirstCrvOffset + i)) ; + pCL->ModifyEnd( vEditInfo[i].ptEnd) ; + CamData* camData = GetCamData( pGeomDB->GetUserObj( nFirstCrvOffset + i)) ; + camData->SetEndPoint( vEditInfo[i].ptEnd) ; } } - nId = m_pMchLua->m_pGeomDB->GetNext( nId) ; + } + + // scorro tutto il vettore delle linee di offset e unisco aggiungendo una linea dove ne ho cancellate + for ( int i = 0 ; i < ssize( vEditInfo) - 1 ; ++i) { + if ( vEditInfo[i].nFlag == EditCrvInfo::DEL || ( vEditInfo[i].nFlag == EditCrvInfo::NOEDIT)) + continue ; + int nPrevId = nFirstCrvOffset + i ; + int c = i + 1 ; + // scorro finché trovo la successiva modificata + while ( c < ssize( vEditInfo) && vEditInfo[c].nFlag == EditCrvInfo::DEL || vEditInfo[c].nFlag == EditCrvInfo::NOEDIT) + ++c ; + if ( vEditInfo[c].nFlag != EditCrvInfo::EDIT) + return GDB_ID_NULL ; + int nNextId = nFirstCrvOffset + c ; + Point3d ptEndCurr, ptStartNext ; + if ( vEditInfo[i].ptEnd.IsValid()) + ptEndCurr = vEditInfo[i].ptEnd ; + else + vOffsetCrvs[i].pCrv->GetEndPoint( ptEndCurr) ; + + if ( vEditInfo[c].ptStart.IsValid()) + ptStartNext = vEditInfo[c].ptStart ; + else + vOffsetCrvs[c].pCrv->GetStartPoint( ptStartNext) ; + + if ( ! AreSamePointApprox( ptEndCurr, ptStartNext)) { + // giunto questi due punti + ICurveLine* pCLprev = GetCurveLine( pGeomDB->GetGeoObj( nPrevId)) ; + Point3d ptIni = pCLprev->GetEnd() ; + ICurveLine* pCLnext = GetCurveLine( pGeomDB->GetGeoObj( nNextId)) ; + Point3d ptFin = pCLnext->GetStart() ; + const CamData* camDataPrev = GetCamData( pGeomDB->GetUserObj( nPrevId)) ; + const CamData* camDataNext = GetCamData( pGeomDB->GetUserObj( nNextId)) ; + Vector3d vtTool = Media( camDataPrev->GetToolDir(), camDataNext->GetToolDir()) ; + Vector3d vtCorr = Media( camDataPrev->GetCorrDir(), camDataNext->GetCorrDir()) ; + Vector3d vtAux = Media( camDataPrev->GetAuxDir(), camDataNext->GetAuxDir()) ; + double dFeed = camDataPrev->GetFeed() ; + int nFlag = camDataPrev->GetFlag() ; + int nFlag2 = camDataPrev->GetFlag2() ; + bool bToolShow = camDataPrev->GetToolShow() ; + AddLinearMove( ptIni, ptFin, pGeomDB, nPathId, vtTool, vtCorr, vtAux, dFeed, nFlag, nFlag2, bToolShow, nPrevId) ; + } + i = c ; } LuaSetParam( L, bOk) ;