Imports System.Net Imports System.Windows.Forms.Integration Imports EgtUILib Public Module SplitAuto Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow) Private m_dLastDT As Double = 0 Public ReadOnly Property dLastDT As Double Get Return m_dLastDT End Get End Property '----------------------------------------------------------------------------------------------- Friend Class SplitMach Public m_nId As Integer Public m_vOthId As New List(Of Integer) Public m_nType As Integer Public m_dSideAng As Double Public m_sLay As String Public m_nEntId As Integer Public m_nNbrId As Integer Public m_nArrId As Integer Public m_nInterf As Integer Public m_bCanStartAll As Boolean Public m_bCanEndAll As Boolean Public m_bStartAll As Boolean Public m_bEndAll As Boolean Public m_bEnabled As Boolean Public m_bPause As Boolean Public m_bEnableInvert As Boolean Public m_bInvert As Boolean Public m_bIsLine As Boolean Public m_dPrevAng As Double Public m_dNextAng As Double Public m_dStartFreeLen As Double Public m_dEndFreeLen As Double Public m_vtDir As Vector3d ' ver 2.6f4: tagli corti gestiti con LeadIn.OUT/LeadOut.OUT Public m_bMngLeadInOnIntCorner As Boolean End Class '----------------------------------------------------------------------------------------------- Friend Function CalculateSplitMachList(nCurrPhase As Integer, ByRef MachSplitList As List(Of SplitMach)) As Boolean ' Pulisco la lista delle lavorazioni MachSplitList.Clear() ' La riempio Dim nOperId As Integer = EgtGetFirstOperation() While nOperId <> GDB_ID.NULL ' verifico sia una lavorazione valida della fase corrente If IsValidMachining(nOperId) And EgtGetOperationPhase(nOperId) = nCurrPhase Then ' se appartiene ad un grezzo attivo la inserisco in lista If IsMachiningInActiveRaw(nOperId) Then Dim Mach As New SplitMach Mach.m_nEntId = GDB_ID.NULL ' identificativo Mach.m_nId = nOperId ' eventuali lavorazioni inglobate Dim sInfo As String = String.Empty If EgtGetInfo(nOperId, INFO_MCH_OTHMID, sInfo) Then Dim sItems() As String = sInfo.Split(",".ToCharArray) For Each sId As String In sItems Dim nId As Integer = 0 StringToInt(sId, nId) If nId > 0 Then Mach.m_vOthId.Add(nId) Next End If ' tipo Mach.m_nType = EgtGetOperationType(nOperId) ' layer di origine EgtGetInfo(nOperId, INFO_MCH_LAYER, Mach.m_sLay) ' se taglio con lama If Mach.m_nType = MCH_OY.SAWING Then ' verifica interferenza If Mach.m_sLay = NAME_OUTLOOP Then EgtVerifyMachining(nOperId, Mach.m_nInterf) For Each nId As Integer In Mach.m_vOthId Dim nRes As Integer = FMI_TYPE.LI Or FMI_TYPE.RM Or FMI_TYPE.LO EgtVerifyMachining(nId, nRes) Mach.m_nInterf = Mach.m_nInterf Or nRes Next Else Mach.m_nInterf = FMI_TYPE.NONE End If ' la imposto come lavorazione corrente EgtSetCurrMachining(nOperId) ' inversione EgtGetMachiningParam(MCH_MP.INVERT, Mach.m_bInvert) ' recupero l'angolo di fianco EgtGetMachiningParam(MCH_MP.SIDEANGLE, Mach.m_dSideAng) ' recupero allungamento iniziale e finale (negativi vicino ad angoli interni) Dim dStartAddLen As Double = -10 EgtGetMachiningParam(MCH_MP.STARTADDLEN, dStartAddLen) Dim dEndAddLen As Double = -10 EgtGetMachiningParam(MCH_MP.ENDADDLEN, dEndAddLen) ' recupero tipo entità, angolo con entità precedente e successiva, lunghezze libere iniziale e finale Mach.m_bIsLine = True Mach.m_dPrevAng = 0 Mach.m_dNextAng = 0 Mach.m_dStartFreeLen = FREELEN_INF + 1 Mach.m_dEndFreeLen = FREELEN_INF + 1 Dim nEntId, nSub As Integer If EgtGetMachiningGeometry(0, nEntId, nSub) Then ' EgtGetType( nEntId) = GDB_TY.CRV_ARC OrElse If EgtGetType(nEntId) = GDB_TY.CRV_COMPO Then Mach.m_bIsLine = False EgtGetInfo(nEntId, If(Not Mach.m_bInvert, INFO_PREVANG, INFO_NEXTANG), Mach.m_dPrevAng) EgtGetInfo(nEntId, If(Not Mach.m_bInvert, INFO_NEXTANG, INFO_PREVANG), Mach.m_dNextAng) EgtGetInfo(nEntId, If(Not Mach.m_bInvert, INFO_START_FREELEN, INFO_END_FREELEN), Mach.m_dStartFreeLen) EgtGetInfo(nEntId, If(Not Mach.m_bInvert, INFO_END_FREELEN, INFO_START_FREELEN), Mach.m_dEndFreeLen) Mach.m_bEnableInvert = GetEnableInvert(nEntId) EgtMidVector(nEntId, GDB_ID.ROOT, Mach.m_vtDir) If Mach.m_bInvert Then Mach.m_vtDir = -Mach.m_vtDir Mach.m_nEntId = nEntId EgtGetInfo(nOperId, "ManageLeadInOnIntCorner", Mach.m_bMngLeadInOnIntCorner) End If ' verifico se trasformabile in un taglio di separazione (almeno da un lato) If (dStartAddLen > -EPS_SMALL Or dEndAddLen > -EPS_SMALL Or Mach.m_bMngLeadInOnIntCorner) And Mach.m_sLay = NAME_OUTLOOP And Mach.m_nInterf = FMI_TYPE.NONE Then Dim nRes As Integer = EgtVerifyCutAsSplitting(nOperId) Dim bIn As Boolean = False Dim bOut As Boolean = False CanExtendSides(Mach, bIn, bOut) Mach.m_bCanStartAll = ((dStartAddLen > -EPS_SMALL Or Mach.m_bMngLeadInOnIntCorner) And (nRes And CAR_RES.LI_OK) <> 0) And Mach.m_dStartFreeLen > FREELEN_INF And Mach.m_bIsLine And bIn Mach.m_bCanEndAll = ((dEndAddLen > -EPS_SMALL Or Mach.m_bMngLeadInOnIntCorner) And (nRes And CAR_RES.LO_OK) <> 0) And Mach.m_dEndFreeLen > FREELEN_INF And Mach.m_bIsLine And bOut If nRes = 0 Then EgtOutLog("Operation ID " & nOperId.ToString & " isn't split cut! verify depth machining.") End If End If ' se trasformabile in taglio di separazione, verifico se lo è If Mach.m_bCanStartAll Or Mach.m_bCanEndAll Then EgtSetCurrMachining(nOperId) Dim nLiType As Integer EgtGetMachiningParam(MCH_MP.LEADINTYPE, nLiType) Dim nLoType As Integer EgtGetMachiningParam(MCH_MP.LEADOUTTYPE, nLoType) Mach.m_bStartAll = (nLiType = MCH_SAW_LI.EXT_CENT Or nLiType = MCH_SAW_LI.EXT_OUT) Mach.m_bEndAll = (nLoType = MCH_SAW_LO.EXT_CENT Or nLoType = MCH_SAW_LO.EXT_OUT) Else Mach.m_bStartAll = False Mach.m_bEndAll = False End If ' Waterjet ElseIf Mach.m_nType = MCH_OY.WATERJETTING Then Mach.m_nInterf = FMI_TYPE.NONE ' recupero l'angolo di fianco EgtGetMachiningParam(MCH_MP.SIDEANGLE, Mach.m_dSideAng) Mach.m_bCanStartAll = False Mach.m_bCanEndAll = False Mach.m_bStartAll = False Mach.m_bEndAll = False ' Forature e fresature Else Mach.m_nInterf = FMI_TYPE.NONE Mach.m_dSideAng = 0 Mach.m_bCanStartAll = False Mach.m_bCanEndAll = False Mach.m_bStartAll = False Mach.m_bEndAll = False End If ' abilitazione Mach.m_bEnabled = Not EgtExistsInfo(nOperId, INFO_MCH_USER_OFF) ' pausa Mach.m_bPause = GetPause(nOperId) ' inserisco in lista MachSplitList.Add(Mach) ' altrimenti la disattivo Else EgtSetOperationMode(nOperId, False) End If End If nOperId = EgtGetNextOperation(nOperId) End While Return True End Function Private Function CanExtendSides(CurrMach As SplitMach, ByRef bIn As Boolean, ByRef bOut As Boolean) As Boolean If CurrMach.m_dPrevAng < -EPS_ANG_SMALL And CurrMach.m_dNextAng > EPS_ANG_SMALL Then ' Posso estendere SOLO l'uscita bOut = True bIn = False ElseIf CurrMach.m_dPrevAng > EPS_ANG_SMALL And CurrMach.m_dNextAng < -EPS_ANG_SMALL Then ' Posso estendere SOLO l'ingresso bIn = True bOut = False ElseIf CurrMach.m_dPrevAng < -EPS_ANG_SMALL And CurrMach.m_dNextAng < -EPS_ANG_SMALL Then ' NON Posso estendere bIn = False bOut = False Else bIn = True bOut = True End If Return True End Function '----------------------------------------------------------------------------------------------- ' calcolo il numero di tipi di lavorazioni Friend Sub CountMachiningType(MachSplit As SplitMach, ByRef nCountSawing As Integer, ByRef nCountWaterjetting As Integer, ByRef nCountOtherMachining As Integer) If MachSplit.m_nType = MCH_OY.SAWING Then nCountSawing += 1 ElseIf MachSplit.m_nType = MCH_OY.WATERJETTING Then nCountWaterjetting += 1 Else nCountOtherMachining += 1 End If End Sub Friend Sub ColorMachining(MachSplit As SplitMach, Optional bReset As Boolean = False) EgtDisableModified() ' Assegno stato Dim bEnabled As Boolean = MachSplit.m_bEnabled Dim nInterf As Integer = If(bReset, FMI_TYPE.NONE, MachSplit.m_nInterf) ' Colore della lavorazione principale ColorSingleMachining(MachSplit.m_nId, MachSplit.m_sLay, MachSplit.m_dSideAng, bEnabled, nInterf) ' Colore delle lavorazioni inglobate For Each nId As Integer In MachSplit.m_vOthId ColorSingleMachining(nId, MachSplit.m_sLay, MachSplit.m_dSideAng, bEnabled, nInterf) Next EgtEnableModified() End Sub Private Sub ColorSingleMachining(nOperId As Integer, sLay As String, dSideAng As Double, bEnabled As Boolean, nInterf As Integer) ' Verifico se è un taglio da sopra o da sotto Dim bOnMach As Boolean = (sLay = NAME_ONPATH Or (sLay = NAME_INLOOP AndAlso EgtExistsInfo(nOperId, INFO_FILOTOP))) Dim bDrip As Boolean = (sLay = NAME_DRIPCUT Or sLay = NAME_UNDERDRILL) ' Recupero il preview della lavorazione Dim nPvId As Integer = GDB_ID.NULL EgtGetInfo(EgtGetFirstNameInGroup(nOperId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) ' Cambio il colore Dim nGrpId As Integer = EgtGetFirstGroupInGroup(nPvId) While nGrpId <> GDB_ID.NULL Dim vCutId As New List(Of Integer) Dim nId As Integer = EgtGetFirstNameInGroup(nGrpId, NAME_PV_CUT) While nId <> GDB_ID.NULL vCutId.Add(nId) nId = EgtGetNextName(nId, NAME_PV_CUT) End While Dim nPrcId As Integer = EgtGetFirstNameInGroup(nGrpId, NAME_PV_PRECUT) Dim nPocId As Integer = EgtGetFirstNameInGroup(nGrpId, NAME_PV_POSTCUT) Dim nDwnCutId As Integer = EgtGetFirstNameInGroup(nGrpId, NAME_PV_DOWN_CUT) Dim nDwnPrcId As Integer = EgtGetFirstNameInGroup(nGrpId, NAME_PV_DOWN_PRECUT) Dim nDwnPocId As Integer = EgtGetFirstNameInGroup(nGrpId, NAME_PV_DOWN_POSTCUT) If Not bEnabled Then For Each nId In vCutId EgtSetColor(nId, COL_MCH_DISABLED) Next EgtSetColor(nDwnCutId, COL_MCH_DISABLED) Dim bFreeStart As Boolean = (nInterf And FMI_TYPE.LI) <> FMI_TYPE.LI EgtSetColor(nPrcId, If(bFreeStart, COL_MCH_DISABLED(), COL_MCH_DIS_INTERF())) EgtSetColor(nDwnPrcId, If(bFreeStart, COL_MCH_DISABLED(), COL_MCH_DIS_INTERF())) Dim bFreeEnd As Boolean = (nInterf And FMI_TYPE.LO) <> FMI_TYPE.LO EgtSetColor(nPocId, If(bFreeEnd, COL_MCH_DISABLED(), COL_MCH_DIS_INTERF())) EgtSetColor(nDwnPocId, If(bFreeEnd, COL_MCH_DISABLED(), COL_MCH_DIS_INTERF())) Else Dim colCut As Color3d If bOnMach Then colCut = COL_MCH_ONCUT() ElseIf bDrip Then colCut = COL_MCH_DRIPCUT() ElseIf Math.Abs(dSideAng) > EPS_ANG_SMALL Then colCut = COL_MCH_CUT_ANG() Else colCut = COL_MCH_CUT() End If For Each nId In vCutId EgtSetColor(nId, colCut) Next EgtSetColor(nDwnCutId, colCut) Dim colStart As Color3d = COL_MCH_INTERF() If (nInterf And FMI_TYPE.LI) <> FMI_TYPE.LI Then If bOnMach Then colStart = COL_MCH_ONFREE() ElseIf bDrip Then colStart = COL_MCH_DRIPFREE() Else colStart = COL_MCH_FREE() End If End If EgtSetColor(nPrcId, colStart) EgtSetColor(nDwnPrcId, colStart) Dim colEnd As Color3d = COL_MCH_INTERF() If (nInterf And FMI_TYPE.LO) <> FMI_TYPE.LO Then If bOnMach Then colEnd = COL_MCH_ONFREE() ElseIf bDrip Then colEnd = COL_MCH_DRIPFREE() Else colEnd = COL_MCH_FREE() End If End If EgtSetColor(nPocId, colEnd) EgtSetColor(nDwnPocId, colEnd) End If nGrpId = EgtGetNextGroup(nGrpId) End While End Sub '----------------------------------------------------------------------------------------------- Friend Sub ShowOnePhaseMachiningPreview(nPhase As Integer) Dim bOldEnMod As Boolean = EgtGetEnableModified() EgtDisableModified() Dim nOpeId = EgtGetFirstOperation() While nOpeId <> GDB_ID.NULL If EgtGetOperationType(nOpeId) <> MCH_OY.DISP And (EgtGetOperationMode(nOpeId) OrElse EgtExistsInfo(nOpeId, INFO_MCH_USER_OFF) OrElse EgtExistsInfo(nOpeId, INFO_MCH_DUPLED)) Then Dim nStatus As Integer = If(EgtGetOperationPhase(nOpeId) = nPhase, GDB_ST.ON_, GDB_ST.OFF) ' Lavorazione principale Dim nPvId As Integer = GDB_ID.NULL EgtGetInfo(EgtGetFirstNameInGroup(nOpeId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) EgtSetStatus(nPvId, nStatus) ' Eventuali lavorazioni inglobate Dim sInfo As String = String.Empty If EgtGetInfo(nOpeId, INFO_MCH_OTHMID, sInfo) Then Dim sItems() As String = sInfo.Split(",".ToCharArray) For Each sId As String In sItems Dim nId As Integer = GDB_ID.NULL StringToInt(sId, nId) Dim nPvId2 As Integer = GDB_ID.NULL EgtGetInfo(EgtGetFirstNameInGroup(nId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId2) EgtSetStatus(nPvId2, nStatus) Next End If End If nOpeId = EgtGetNextOperation(nOpeId) End While If bOldEnMod Then EgtEnableModified() End Sub Friend Sub ShowAllPhasesMachiningPreview() Dim bOldEnMod As Boolean = EgtGetEnableModified() EgtDisableModified() Dim nOpeId = EgtGetFirstOperation() While nOpeId <> GDB_ID.NULL If EgtGetOperationType(nOpeId) <> MCH_OY.DISP And (EgtGetOperationMode(nOpeId) OrElse EgtExistsInfo(nOpeId, INFO_MCH_USER_OFF) OrElse EgtExistsInfo(nOpeId, INFO_MCH_DUPLED)) Then Dim nStatus As Integer = GDB_ST.ON_ ' Lavorazione principale Dim nPvId As Integer = GDB_ID.NULL EgtGetInfo(EgtGetFirstNameInGroup(nOpeId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) EgtSetStatus(nPvId, nStatus) ' Eventuali lavorazioni inglobate Dim sInfo As String = String.Empty If EgtGetInfo(nOpeId, INFO_MCH_OTHMID, sInfo) Then Dim sItems() As String = sInfo.Split(",".ToCharArray) For Each sId As String In sItems Dim nId As Integer = GDB_ID.NULL StringToInt(sId, nId) Dim nPvId2 As Integer = GDB_ID.NULL EgtGetInfo(EgtGetFirstNameInGroup(nId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId2) EgtSetStatus(nPvId2, nStatus) Next End If End If nOpeId = EgtGetNextOperation(nOpeId) End While If bOldEnMod Then EgtEnableModified() End Sub '----------------------------------------------------------------------------------------------- Friend Function SplitRawParts(nPrevPhase As Integer, vCuts() As Integer, ByRef vNewRaws As List(Of Integer)) As Boolean ' Aggiorno preview di questi tagli lasciandoli nella lavorazione For Each nCut As Integer In vCuts UpdateMachiningPreview(nCut, False) Next ' Creo nuova fase Dim nNewPhase As Integer = EgtAddPhase() ' Origine della tavola Dim ptOri As Point3d EgtGetTableRef(1, ptOri) Dim vtOri As New Vector3d(ptOri.x, ptOri.y, ptOri.z) ' ---------------------------------- GREZZI ---------------------------------- ' Eseguo eventuali spezzature dei grezzi e vi sposto i pezzi (i grezzi devono essere sempre copiati per Registrazione con rotazione) Dim nRawId As Integer = EgtGetFirstRawPart() While nRawId <> GDB_ID.NULL ' se il grezzo è presente nella fase precedente If EgtVerifyRawPartPhase(nRawId, nPrevPhase) Then ' Calcolo nuovi grezzi Dim nRaw1Id = EgtSplitFlatRawPartWithMachinings(nRawId, vCuts) ' Fisso posizione dei nuovi grezzi Dim nNewRawId = nRaw1Id While nNewRawId <> GDB_ID.NULL Dim ptMin, ptMax As Point3d EgtGetRawPartBBox(nNewRawId, ptMin, ptMax) EgtMoveToCornerRawPart(nNewRawId, ptMin - vtOri, MCH_CR.BL) nNewRawId = EgtGetNextRawPart(nNewRawId) End While ' Se almeno 2 grezzi da uno vecchio, li considero nuovi If EgtGetNextRawPart(nRaw1Id) <> GDB_ID.NULL Then nNewRawId = nRaw1Id While nNewRawId <> GDB_ID.NULL vNewRaws.Add(nNewRawId) nNewRawId = EgtGetNextRawPart(nNewRawId) End While Else ' verifico che nella fase precedente è stato definito come sfrido, allora lo riassegno Dim nVal As Integer = 0 EgtGetInfo(nRawId, K_ISNEWSCRAPS, nVal) If nVal = 1 Or nVal = 2 Or nVal = 3 Then EgtSetInfo(nRaw1Id, K_ISNEWSCRAPS, "3") End If End If ' Assegno ai nuovi grezzi eventuale texture del grezzo originale Dim nSolidId = EgtGetFirstNameInGroup(nRawId, NAME_RAW_SOLID) Dim nameTxr As String = String.Empty If EgtGetTextureName(nSolidId, nameTxr) Then Dim refTxr As New Frame3d EgtGetTextureFrame(nSolidId, GDB_ID.ROOT, refTxr) nNewRawId = nRaw1Id While nNewRawId <> GDB_ID.NULL ' Carico la texture sul nuovo grezzo Dim nNewSolidId = EgtGetFirstNameInGroup(nNewRawId, NAME_RAW_SOLID) EgtSetTextureName(nNewSolidId, nameTxr) ' Sistemo il riferimento della texture EgtSetTextureFrame(nNewSolidId, refTxr, GDB_RT.GLOB) ' Passo al grezzo successivo nNewRawId = EgtGetNextRawPart(nNewRawId) End While End If End If ' passo al successivo grezzo nRawId = EgtGetNextRawPart(nRawId) End While ' ---------------------------------- GREZZI ---------------------------------- ' Cancello preview dei tagli allungati dalla lavorazione For Each nCut As Integer In vCuts RemoveMachiningPreview(nCut) Next ' ---------------------------------- LAVORAZIONI ---------------------------------- ChangeOperationPhase(nNewPhase) ' ---------------------------------- LAVORAZIONI ---------------------------------- Return True End Function ' Sposta le lavorzioni della fase precedente a quella indicata Friend Sub ChangeOperationPhase_ERR(nNewPhase As Integer) ' Sposto tutte le lavorazioni disabilitate e le eventuali inglobate nella nuova fase Dim nId = EgtGetFirstOperation() While nId <> GDB_ID.NULL Dim nNextId = EgtGetNextOperation(nId) If IsValidMachining(nId) And EgtGetOperationPhase(nId) = nNewPhase - 1 And EgtExistsInfo(nId, INFO_MCH_USER_OFF) Then ' sposto la lavorazione EgtChangeOperationPhase(nId, nNewPhase) ' sposto le inglobate Dim sInfo As String = String.Empty If EgtGetInfo(nId, INFO_MCH_OTHMID, sInfo) Then Dim sItems() As String = sInfo.Split(",".ToCharArray) For Each sId2 As String In sItems Dim nId2 As Integer = 0 StringToInt(sId2, nId2) If nId2 > 0 Then EgtChangeOperationPhase(nId2, nNewPhase) Next End If End If nId = nNextId End While End Sub ' Miglioramento della gestione delle lavorazioni Friend Sub ChangeOperationPhase(nNewPhase As Integer) ' creo l'elenco delle lavorazioni che devono essere sposate Dim MchList As New List(Of Integer) ' Recupero le lavorazioni disabilitate e le eventuali inglobate nella nuova fase Dim nId = EgtGetFirstOperation() While nId <> GDB_ID.NULL Dim nNextId = EgtGetNextOperation(nId) If IsValidMachining(nId) And EgtGetOperationPhase(nId) = nNewPhase - 1 And EgtExistsInfo(nId, INFO_MCH_USER_OFF) Then ' Provo ad inserire la lavorazione nell'elenco AddMach(MchList, nId) ' sposto le inglobate Dim sInfo As String = String.Empty If EgtGetInfo(nId, INFO_MCH_OTHMID, sInfo) Then Dim sItems() As String = sInfo.Split(",".ToCharArray) For Each sId2 As String In sItems Dim nId2 As Integer = 0 StringToInt(sId2, nId2) If nId2 > 0 Then ' Provo ad inserire la lavorazione nell'elenco AddMach(MchList, nId2) End If Next End If End If nId = nNextId End While ' Procedo ora a spostare le lavorazioni nella nuova disposizione For Each ItemMchId As Integer In MchList EgtChangeOperationPhase(ItemMchId, nNewPhase) Next End Sub ' Inserisce gli inidici delle lavorazioni evitando di inserire dei doppioni Private Sub AddMach(MchList As List(Of Integer), IdMch As Integer) For Each Item As Integer In MchList If IdMch = Item Then Return End If Next MchList.Add(IdMch) End Sub '----------------------------------------------------------------------------------------------- Friend Function CalculateSplitAuto() As Boolean ' Fase iniziale EgtSetCurrPhase(1) ' Cancello tutte le lavorazioni EraseMachinings(GDB_ID.NULL) ' Reinserisco tutte le lavorazioni Dim nWarn As Integer = 0 AddMachinings(GDB_ID.NULL, nWarn) If nWarn = 1 Then m_MainWindow.m_CurrentProjectPageUC.SetWarningMessage(EgtMsg(MSG_SPLITPAGEUC + 11)) ' Lama troppo grande per utilizzo ventosa ' Carico ventose LoadVacuumCups() ' Lancio calcolo separazione Dim bFinished As Boolean = False While CalculateOnePhaseSplitAuto(bFinished) If bFinished Then Exit While End If End While ' Se non finito con successo, verifico se necessario limitare lavorazioni If Not bFinished Then If Not TestMachiningCurrPhaseForStrict() Then m_MainWindow.m_CurrentProjectPageUC.SetWarningMessage(EgtMsg(90321)) 'Ridotte alcune lavorazioni per evitare interferenze End If End If EgtSetCurrPhase(1) ' Scarico ventose RemoveVacuumCups() Return bFinished End Function '----------------------------------------------------------------------------------------------- Friend Function CalculateOnePhaseSplitAuto(ByRef bFinished As Boolean) As Boolean ' Faccio ordine automatico delle lavorazioni If Not SortAllMachinings() Then Return False m_MainWindow.m_CurrentProjectPageUC.SetOrderMachiningFlag() ' Recupero l'indice della fase corrente Dim nCurrPhase As Integer = EgtGetCurrPhase() ' Preparo la lista delle lavorazioni Dim MachSplitList As New List(Of SplitMach) If Not CalculateSplitMachList(nCurrPhase, MachSplitList) Then Return False ' Se non ci sono interferenze If Not FindInterferences(MachSplitList) Then ' Abilito tutte le lavorazioni della lista EnableAllMachinings(MachSplitList) ' Dichiaro conclusione ed esco bFinished = True Return True End If ' Disabilito tutte le lavorazioni della lista DisableAllMachinings(MachSplitList) ' Cerco il miglior taglio di separazione Dim nCutInd As Integer = FindBestSeparationCut(MachSplitList) If nCutInd < 0 Then Return False ' Eseguo il taglio If Not MakeSeparatingCut(MachSplitList(nCutInd).m_nId) Then Return False MachSplitList(nCutInd).m_bEnabled = True MachSplitList(nCutInd).m_bStartAll = True MachSplitList(nCutInd).m_bEndAll = True ColorMachining(MachSplitList(nCutInd)) ' Spezzo i grezzi creando una nuova fase di lavoro Dim vCuts() As Integer = {MachSplitList(nCutInd).m_nId} Dim vNewRaws As New List(Of Integer) If SplitRawParts(nCurrPhase, vCuts, vNewRaws) Then ' Eseguo gli spostamenti dei grezzi If MoveRawParts(MachSplitList(nCutInd).m_nId, vNewRaws) Then While vNewRaws.Count() >= 4 vNewRaws.RemoveAt(0) vNewRaws.RemoveAt(0) MoveRawParts(MachSplitList(nCutInd).m_nId, vNewRaws) End While bFinished = False Return True End If End If ' Ci sono stati errori dopo aver creato la nuova fase, ripristino la vecchia RemoveLastPhase() bFinished = False Return False End Function '----------------------------------------------------------------------------------------------- '----------------------------------------------------------------------------------------------- Private Function FindInterferences(ByRef MachSplitList As List(Of SplitMach)) As Boolean Dim bInterf As Boolean = False For Each MachSplit As SplitMach In MachSplitList If MachSplit.m_nInterf <> FMI_TYPE.NONE Then bInterf = True Exit For End If Next Return bInterf End Function Private Function EnableAllMachinings(ByRef MachSplitList As List(Of SplitMach)) As Boolean For nI As Integer = 0 To MachSplitList.Count() - 1 If Not MachSplitList(nI).m_bEnabled Then MachSplitList(nI).m_bEnabled = True EgtSetOperationMode(MachSplitList(nI).m_nId, True) EgtRemoveInfo(MachSplitList(nI).m_nId, INFO_MCH_USER_OFF) ColorMachining(MachSplitList(nI)) End If Next Return True End Function Private Function DisableAllMachinings(ByRef MachSplitList As List(Of SplitMach)) As Boolean For nI As Integer = 0 To MachSplitList.Count() - 1 If MachSplitList(nI).m_bEnabled Then MachSplitList(nI).m_bEnabled = False EgtSetOperationMode(MachSplitList(nI).m_nId, False) EgtSetInfo(MachSplitList(nI).m_nId, INFO_MCH_USER_OFF, True) ColorMachining(MachSplitList(nI)) End If Next Return True End Function Private Function FindBestSeparationCut(MachSplitList As List(Of SplitMach)) As Integer Dim nInd As Integer = -1 Dim nMaxInterf As Integer = 0 m_dLastDT = 0 For nI As Integer = 0 To MachSplitList.Count() - 1 Dim MachSplit As SplitMach = MachSplitList(nI) ' Se non allungabile ad entrambi gli estremi, vado oltre If Not MachSplit.m_bCanStartAll Or Not MachSplit.m_bCanEndAll Then Continue For ' Se ci sono lavorazioni componenti, calcolo preview completo in lavorazione If MachSplit.m_vOthId.Count() > 0 Then UpdateMachiningPreview(MachSplit.m_nId, False) End If ' Contatore interferenze altri tagli con taglio corrente Dim nCurrInterf As Integer = 0 ' Lunghezza baffi altri tagli che interferiscono su taglio corrente Dim dCurrInterfLen As Double = 0 ' Determino quanti tagli con interferenza interseca For Each MachSplit2 As SplitMach In MachSplitList ' Se coincide con il precedente, vado oltre If MachSplit2.m_nId = MachSplit.m_nId Then Continue For ' Se non interferisce, vado oltre If MachSplit2.m_nInterf = FMI_TYPE.NONE Then Continue For ' Se ci sono lavorazioni componenti, calcolo preview completo in lavorazione If MachSplit2.m_vOthId.Count() > 0 Then UpdateMachiningPreview(MachSplit2.m_nId, False) End If ' Eseguo verifica tra le lavorazioni Dim bInterf As Boolean = False If GetInterferenceWithOtherCut(MachSplit.m_nId, MachSplit2.m_nId, MachSplit2.m_nInterf) Then bInterf = True ' Recupero lunghezza baffo secondo taglio Dim nPvId As Integer = GDB_ID.NULL EgtGetInfo(EgtGetFirstNameInGroup(MachSplit2.m_nId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) Dim dDT As Double If EgtGetInfo(EgtGetFirstGroupInGroup(nPvId), "DT", dDT) And dDT > dCurrInterfLen Then dCurrInterfLen = dDT End If End If If bInterf Then nCurrInterf += 1 ' Rimozione eventuale preview completo in lavorazione RemoveMachiningPreview(MachSplit2.m_nId) Next ' Verifico se taglio corrente è nuovo campione If nCurrInterf > nMaxInterf Then nMaxInterf = nCurrInterf nInd = nI m_dLastDT = dCurrInterfLen End If ' Rimozione eventuale preview completo in lavorazione RemoveMachiningPreview(MachSplit.m_nId) Next Return nInd End Function Private Function GetInterferenceWithOtherCut(nId As Integer, nId2 As Integer, nInterf2 As Integer) As Boolean ' Se il secondo non ha interferenze, esco subito If nInterf2 = FMI_TYPE.NONE Then Return False ' Regione di taglio ridotta del primo Dim nPvId As Integer = EgtGetFirstNameInGroup(nId, NAME_PREVIEW) If EgtGetGroupObjs(nPvId) = 0 Then EgtGetInfo(nPvId, INFO_PV_ONPART_ID, nPvId) Dim nRCutId As Integer = EgtGetFirstNameInGroup(EgtGetFirstGroupInGroup(nPvId), NAME_PV_RCUT) ' Se il secondo ha l'attacco che interferisce If (nInterf2 And FMI_TYPE.LI) <> 0 Then ' Recupero regione dell'attacco Dim nPv2Id As Integer = EgtGetFirstNameInGroup(nId2, NAME_PREVIEW) If EgtGetGroupObjs(nPv2Id) = 0 Then EgtGetInfo(nPv2Id, INFO_PV_ONPART_ID, nPv2Id) Dim nRLiCut2Id As Integer = EgtGetFirstNameInGroup(EgtGetFirstGroupInGroup(nPv2Id), NAME_PV_RLICUT) ' Verifico se questa regione interferisce con quella del taglio di riferimento If EgtSurfFrChunkSimpleClassify(nRCutId, 0, nRLiCut2Id, 0, 20 * EPS_SMALL) <> REGC.OUT Then Return True End If ' Se il secondo ha l'uscita che interferisce If (nInterf2 And FMI_TYPE.LO) <> 0 Then ' Recupero Id della regione dell'uscita Dim nPv2Id As Integer = EgtGetFirstNameInGroup(nId2, NAME_PREVIEW) If EgtGetGroupObjs(nPv2Id) = 0 Then EgtGetInfo(nPv2Id, INFO_PV_ONPART_ID, nPv2Id) Dim nRLoCut2Id As Integer = EgtGetFirstNameInGroup(EgtGetFirstGroupInGroup(nPv2Id), NAME_PV_RLOCUT) ' Verifico se questa regione interferisce con quella del taglio di riferimento If EgtSurfFrChunkSimpleClassify(nRCutId, 0, nRLoCut2Id, 0, 20 * EPS_SMALL) <> REGC.OUT Then Return True End If Return False End Function Private Function MakeSeparatingCut(nCutId As Integer) As Boolean EgtSetCurrMachining(nCutId) Dim nLiPrev As Integer EgtGetMachiningParam(MCH_MP.LEADINTYPE, nLiPrev) Dim nLoPrev As Integer EgtGetMachiningParam(MCH_MP.LEADOUTTYPE, nLoPrev) ' allungo If nLiPrev = MCH_SAW_LI.OUT Then EgtSetMachiningParam(MCH_MP.LEADINTYPE, MCH_SAW_LI.EXT_OUT) Else EgtSetMachiningParam(MCH_MP.LEADINTYPE, MCH_SAW_LI.EXT_CENT) End If If nLoPrev = MCH_SAW_LO.OUT Then EgtSetMachiningParam(MCH_MP.LEADOUTTYPE, MCH_SAW_LO.EXT_OUT) Else EgtSetMachiningParam(MCH_MP.LEADOUTTYPE, MCH_SAW_LO.EXT_CENT) End If UpdateMachiningPreview(nCutId, True) EgtSetOperationMode(nCutId, True) EgtRemoveInfo(nCutId, INFO_MCH_USER_OFF) Return True End Function Private Function MoveRawParts(nCutId As Integer, vNewRaws As List(Of Integer)) As Boolean ' Almeno 2 nuovi grezzi (dovrebbero essere solo 2) If vNewRaws.Count() < 2 Then Return False ' Privilegio il grezzo più piccolo (lo porto in seconda posizione per essere mosso per primo) If GetSmallerRaw(vNewRaws(0), vNewRaws(1)) = 1 Then Dim nTmp As Integer = vNewRaws(0) vNewRaws(0) = vNewRaws(1) vNewRaws(1) = nTmp End If ' Centri dei primi 2 grezzi Dim ptCen0 As Point3d If Not EgtGetRawPartCenter(vNewRaws(0), ptCen0) Then Return False Dim ptCen1 As Point3d If Not EgtGetRawPartCenter(vNewRaws(1), ptCen1) Then Return False ' Direzione del taglio EgtSetCurrMachining(nCutId) Dim nEntId, nSub As Integer If Not EgtGetMachiningGeometry(0, nEntId, nSub) Then Return False Dim vtCutDir As Vector3d EgtStartVector(nEntId, GDB_ID.ROOT, vtCutDir) ' Distanza minima di spostamento Dim dExtraL As Double = 0 EgtMdbGetGeneralParam(MCH_GP.EXTRALONCUTREG, dExtraL) Dim dMinMove As Double = m_dLastDT + dExtraL + 1 ' Decido cosa muovere Dim nDispId As Integer = EgtGetPhaseDisposition(EgtGetCurrPhase()) Dim dDeltaX = ptCen1.x - ptCen0.x Dim dDeltaY = ptCen1.y - ptCen0.y If Math.Abs(dDeltaX) < Math.Abs(dDeltaY) Then Dim vtMoveY As New Vector3d(0, dMinMove / Math.Abs(vtCutDir.x), 0) If dDeltaY < 0 Then vtMoveY = -vtMoveY If Not ExecMove(nDispId, vNewRaws, vtMoveY, dMinMove) Then If Math.Abs(dDeltaX) > 0.2 Then Dim vtMoveX As New Vector3d(dMinMove / Math.Abs(vtCutDir.y), 0, 0) If dDeltaX < 0 Then vtMoveX = -vtMoveX If Not ExecMove(nDispId, vNewRaws, vtMoveX, dMinMove) Then Return False End If Else Return False End If End If Else Dim vtMoveX As New Vector3d(dMinMove / Math.Abs(vtCutDir.y), 0, 0) If dDeltaX < 0 Then vtMoveX = -vtMoveX If Not ExecMove(nDispId, vNewRaws, vtMoveX, dMinMove) Then If Math.Abs(dDeltaY) > 0.2 Then Dim vtMoveY As New Vector3d(0, dMinMove / Math.Abs(vtCutDir.x), 0) If dDeltaY < 0 Then vtMoveY = -vtMoveY If Not ExecMove(nDispId, vNewRaws, vtMoveY, dMinMove) Then Return False End If Else Return False End If End If End If Return True End Function Private Function TestMachiningCurrPhaseForStrict() As Boolean ' Recupero l'indice della fase corrente Dim nCurrPhase As Integer = EgtGetCurrPhase() ' Preparo la lista delle lavorazioni Dim MachSplitList As New List(Of SplitMach) If Not CalculateSplitMachList(nCurrPhase, MachSplitList) Then Return False ' Affondamento ridotto Dim dReducedDepth As Double = GetPrivateProfileDouble(S_MACH_NEST, K_MACH_REDUCEDDEPTH, 1, m_MainWindow.GetMachIniFile()) ' Restringo o rialzo lavorazioni abilitate ma con interferenza Dim bModified As Boolean = False For Each Mach As SplitMach In MachSplitList If Mach.m_bEnabled And Mach.m_nInterf <> FMI_TYPE.NONE Then If AdjustMachining(Mach.m_nId, Mach.m_nInterf, dReducedDepth) Then bModified = True End If End If Next Return bModified End Function Private Function GetSmallerRaw(nRaw1Id As Integer, nRaw2Id As Integer) As Integer ' Area del primo grezzo Dim nRc1Id As Integer = EgtGetFirstNameInGroup(nRaw1Id, NAME_RAW_OUTLINE) Dim dArea1 As Double = 0 If Not EgtCurveAreaXY(nRc1Id, dArea1) Then Return 0 ' Area del secondo grezzo Dim nRc2Id As Integer = EgtGetFirstNameInGroup(nRaw2Id, NAME_RAW_OUTLINE) Dim dArea2 As Double = 0 If Not EgtCurveAreaXY(nRc2Id, dArea2) Then Return 0 ' Confronto le aree If dArea1 < dArea2 Then Return 1 Else Return 2 End If End Function Private Function ExecMove(nDispId As Integer, vNewRaws As List(Of Integer), vtMove As Vector3d, dMinMove As Double) As Boolean Dim bTwoHeadVac As Boolean = (EgtGetHeadId(VACUUM_HEAD_2) <> GDB_ID.NULL) Dim rmData As New RawMoveData Dim vtMove2 As Vector3d = -vtMove VacuumCups.ResetHeadName() Dim bPutVacuum As Boolean = PutVacuumCupsOnRaw(vNewRaws(1), rmData) If Not bPutVacuum And bTwoHeadVac Then bPutVacuum = PutVacuumCupsOnRaw(vNewRaws(1), rmData) If bPutVacuum AndAlso SafeMoveRawPart(vNewRaws(1), vtMove, dMinMove) Then rmData.m_vtRawMove = vtMove SaveOneMoveInfoInDisposition(nDispId, rmData) Return True End If VacuumCups.ResetHeadName() Dim bPut2Vacuum As Boolean = PutVacuumCupsOnRaw(vNewRaws(0), rmData) If Not bPut2Vacuum And bTwoHeadVac Then bPutVacuum = PutVacuumCupsOnRaw(vNewRaws(0), rmData) If bPut2Vacuum AndAlso SafeMoveRawPart(vNewRaws(0), vtMove2, dMinMove) Then rmData.m_vtRawMove = vtMove2 SaveOneMoveInfoInDisposition(nDispId, rmData) Return True End If Return False End Function Private Function SafeMoveRawPart(nRawId As Integer, ByRef vtMove As Vector3d, dMindist As Double) As Boolean ' Spostamento originale Dim vtOriMove As New Vector3d(vtMove) ' Livello di movimento Dim nMoveLevel As Integer = GetPrivateProfileInt(S_SPLIT, K_MOVE_LEV, 5, m_MainWindow.GetIniFile()) Dim nMove As Integer = 1 ' Se esce dalla tavola, movimento già annullato ed esco con errore If Not EgtMoveRawPart(nRawId, vtOriMove) Then Return False ' Se interferisce con altri grezzi, annullo movimento ed esco con errore If Not VerifyRawWithOtherRaws(nRawId, dMindist) Then EgtMoveRawPart(nRawId, -vtOriMove) Return False End If If nMoveLevel < 2 Then Return True ' Provo ad aggiungere un altro movimento If EgtMoveRawPart(nRawId, vtOriMove) Then If VerifyRawWithOtherRaws(nRawId, dMindist) Then vtMove += vtOriMove nMove += 1 If nMoveLevel = nMove Then Return True Else EgtMoveRawPart(nRawId, -vtOriMove) End If End If ' Provo ad aggiungere un altro movimento If EgtMoveRawPart(nRawId, vtOriMove) Then If VerifyRawWithOtherRaws(nRawId, dMindist) Then vtMove += vtOriMove nMove += 1 If nMoveLevel = nMove Then Return True Else EgtMoveRawPart(nRawId, -vtOriMove) End If End If ' Provo ad aggiungere un movimento dimezzato If EgtMoveRawPart(nRawId, 0.5 * vtOriMove) Then If VerifyRawWithOtherRaws(nRawId, dMindist) Then vtMove += 0.5 * vtOriMove nMove += 1 If nMoveLevel = nMove Then Return True Else EgtMoveRawPart(nRawId, -0.5 * vtOriMove) End If End If ' Provo ad aggiungere un movimento 1/4 If EgtMoveRawPart(nRawId, 0.25 * vtOriMove) Then If VerifyRawWithOtherRaws(nRawId, dMindist) Then vtMove += 0.25 * vtOriMove Else EgtMoveRawPart(nRawId, -0.25 * vtOriMove) End If End If Return True End Function Private Function VerifyRawWithOtherRaws(nRawId As Integer, dMindist As Double) As Boolean ' Contorno del grezzo in esame Dim nRcId As Integer = EgtGetFirstNameInGroup(nRawId, NAME_RAW_OUTLINE) If nRcId = GDB_ID.NULL Then Return False ' Fase corrente Dim nCurrPhase As Integer = EgtGetCurrPhase() ' Recupero elenco dei contorni degli altri grezzi della fase indicata Dim OthRawList As New List(Of Integer) Dim nOthId As Integer = EgtGetFirstRawPart() While nOthId <> GDB_ID.NULL If EgtVerifyRawPartPhase(nOthId, nCurrPhase) Then If nOthId <> nRawId Then Dim nOthRcId As Integer = EgtGetFirstNameInGroup(nOthId, NAME_RAW_OUTLINE) If nOthRcId <> GDB_ID.NULL Then OthRawList.Add(nOthRcId) End If End If nOthId = EgtGetNextRawPart(nOthId) End While ' Box del grezzo in esame Dim b3Raw As New BBox3d EgtGetBBoxGlob(nRcId, GDB_BB.STANDARD, b3Raw) b3Raw.Expand(dMindist) ' Creo la curva offsettata della minima distanza (considero solo la prima, ovvero la più lunga) Dim nCount As Integer = 0 Dim nOffsId = EgtOffsetCurveAdv(nRcId, dMindist, OFF_TYPE.FILLET, nCount) ' Verifico Dim bInterf As Boolean = False For Each nId As Integer In OthRawList Dim b3OthRaw As New BBox3d EgtGetBBoxGlob(nId, GDB_BB.STANDARD, b3OthRaw) ' Se i box interferiscono If b3Raw.OverlapsXY(b3OthRaw) Then ' Verifico i contorni esterni If EgtClosedCurveClassify(nOffsId, nId) <> CCREGC.OUT Then bInterf = True Exit For End If End If Next ' Cancello curve offset For i As Integer = 0 To nCount - 1 EgtErase(nOffsId + i) Next Return (Not bInterf) End Function Public Function MaxCuttingMustache(dMustache As Double) As Double Dim MachSplitList As New List(Of SplitMach) ' Recupero l'indice della fase corrente Dim nCurrPhase As Integer = EgtGetCurrPhase() ' se non è stata creata nessuna lista allora restituisco il valore di Default If Not CalculateSplitMachList(nCurrPhase, MachSplitList) Then Return dMustache Dim NewMustache As Double = 0 Dim ItemMachSplit As SplitMach For Each ItemMachSplit In MachSplitList ' Recupero lunghezza baffo secondo taglio Dim nPvId As Integer = GDB_ID.NULL EgtGetInfo(EgtGetFirstNameInGroup(ItemMachSplit.m_nId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) Dim dDT As Double If EgtGetInfo(EgtGetFirstGroupInGroup(nPvId), "DT", dDT) Then If NewMustache < dDT Then NewMustache = dDT End If Next Dim dExtraL As Double = 0 EgtMdbGetGeneralParam(MCH_GP.EXTRALONCUTREG, dExtraL) ' se esiste il valore di un baffo allora sovrascrivo il valore di default If NewMustache > 0 Then dMustache = Math.Ceiling(NewMustache) End If Return dMustache + dExtraL End Function End Module