Imports EgtUILib Module VacuumCups ' Tipo manipolatore con ventosa (0=assente, 1=dietro, 2=laterale) Private m_nVacType As Integer = 0 ' Dati del manipolatore Private m_nTempId As Integer = GDB_ID.NULL Private m_nVacId As Integer = GDB_ID.NULL Private m_nRefId As Integer = GDB_ID.NULL ' Nome del gruppo temporaneo per le ventose Private Const VACTMP_GRP As String = "VacTmp" '----------------------------------------------------------------------------------------------- Friend Class RawMoveData Public m_nId As Integer Public m_vtRawMove As Vector3d Public m_dRawAngRotDeg As Double Public m_vtDelta As Vector3d Public m_dAngRotDeg As Double Public m_sCups As String Sub New() m_nId = GDB_ID.NULL m_vtRawMove = Vector3d.NULL() m_dRawAngRotDeg = 0 m_vtDelta = Vector3d.NULL() m_dAngRotDeg = 0 m_sCups = String.Empty End Sub Sub New(nId As Integer) m_nId = nId m_vtRawMove = Vector3d.NULL() m_dRawAngRotDeg = 0 m_vtDelta = Vector3d.NULL() m_dAngRotDeg = 0 m_sCups = String.Empty End Sub End Class '----------------------------------------------------------------------------------------------- Friend Function GetVacuumType() As Integer Return m_nVacType End Function Friend Function GetVacuumId() As Integer Return m_nVacId End Function Friend Function LoadVacuumCups() As Boolean ' Leggo tipo manipolatore con ventosa m_nVacType = 0 EgtGetInfo(EgtGetHeadId(VACUUM_HEAD), KEY_VAC_TYPE, m_nVacType) ' Cancello eventuali vecchie ventose RemoveVacuumCups() ' Identificativo ventose nella macchina Dim nLayId As Integer = EgtGetFirstNameInGroup(EgtGetHeadId(VACUUM_HEAD), VACUUM_HEAD_LAYOUT) If nLayId = GDB_ID.NULL Then Return False ' Identificativo riferimento della testa nella macchina Dim nT1Id As Integer = EgtGetFirstNameInGroup(EgtGetHeadId(VACUUM_HEAD), HEAD_FIRST_EXIT) If nT1Id = GDB_ID.NULL Then Return False ' Creo gruppo temporaneo in cui copiarli m_nTempId = EgtCreateGroup(GDB_ID.ROOT) If m_nTempId = GDB_ID.NULL Then Return False EgtSetName(m_nTempId, VACTMP_GRP) EgtSetLevel(m_nTempId, GDB_LV.TEMP) ' Eseguo copia in globale m_nVacId = EgtCopyGlob(nLayId, m_nTempId) If m_nVacId = GDB_ID.NULL Then Return False ' Nascondo il gruppo ma rendo visibili le curve di contorno delle ventose EgtSetStatus(m_nVacId, GDB_ST.OFF) Dim nId As Integer = EgtGetFirstInGroup(m_nVacId) While nId <> GDB_ID.NULL Select Case EgtGetType(nId) Case GDB_TY.CRV_LINE, GDB_TY.CRV_ARC, GDB_TY.CRV_BEZ, GDB_TY.CRV_COMPO EgtSetStatus(nId, GDB_ST.ON_) Case Else EgtSetStatus(nId, GDB_ST.OFF) End Select nId = EgtGetNext(nId) End While m_nRefId = EgtCopyGlob(nT1Id, m_nVacId) If m_nRefId = GDB_ID.NULL Then Return False EgtSetStatus(m_nRefId, GDB_ST.ON_) Return True End Function Friend Function RemoveVacuumCups() As Boolean ' Cancello eventuali gruppi per ventose usati appena prima EgtErase(m_nTempId) m_nTempId = GDB_ID.NULL m_nVacId = GDB_ID.NULL m_nRefId = GDB_ID.NULL ' Cancello eventuali vecchi gruppi per ventose Dim nId As Integer = EgtGetFirstNameInGroup(GDB_ID.ROOT, VACTMP_GRP) While nId <> GDB_ID.NULL Dim nNextId As Integer = EgtGetNextName(nId, VACTMP_GRP) EgtErase(nId) nId = nNextId End While Return True End Function Friend Function ResetVacuumCups() As Boolean ' Ripristino posizione e rotazione originali Dim frOriRef As New Frame3d EgtFrame(EgtGetFirstNameInGroup(EgtGetHeadId(VACUUM_HEAD), HEAD_FIRST_EXIT), GDB_ID.ROOT, frOriRef) Dim frCurrRef As New Frame3d EgtFrame(m_nRefId, GDB_ID.ROOT, frCurrRef) EgtMove(m_nVacId, frOriRef.Orig() - frCurrRef.Orig(), GDB_RT.GLOB) frCurrRef.ToLoc(frOriRef) Dim dLen, dAngVertDeg, dAngOrizzDeg As Double frCurrRef.VersX().ToSpherical(dLen, dAngVertDeg, dAngOrizzDeg) EgtRotate(m_nVacId, frOriRef.Orig(), frOriRef.VersZ(), -dAngOrizzDeg, GDB_RT.GLOB) ' Ripristino visualizzazione originale Dim nId As Integer = EgtGetFirstInGroup(m_nVacId) While nId <> GDB_ID.NULL Select Case EgtGetType(nId) Case GDB_TY.CRV_LINE, GDB_TY.CRV_ARC, GDB_TY.CRV_BEZ, GDB_TY.CRV_COMPO EgtSetStatus(nId, GDB_ST.ON_) Case Else EgtSetStatus(nId, GDB_ST.OFF) End Select nId = EgtGetNext(nId) End While EgtSetStatus(m_nRefId, GDB_ST.ON_) Return True End Function Friend Function PutVacuumCupsOnRaw(nRawId As Integer, ByRef rmData As RawMoveData) As Boolean ' Ripristino posizione originale ventose ResetVacuumCups() ' Box e baricentro del grezzo (riportato sopra al grezzo) Dim b3Raw As New BBox3d EgtGetRawPartBBox(nRawId, b3Raw) Dim ptRawCen As Point3d EgtGetRawPartCenter(nRawId, ptRawCen) ptRawCen.z += b3Raw.DimZ() / 2 ' Se non esiste, creo la regione del kerf del grezzo Dim nKerfId As Integer = EgtGetFirstNameInGroup(nRawId, NAME_KERF) Dim nRKerfId = EgtGetFirstNameInGroup(nRawId, NAME_KERF_REGION) If nRKerfId = GDB_ID.NULL Then nRKerfId = EgtCreateSurfFlatRegion(nRawId, nKerfId) ' se non sono riuscito a crearla, allora è nulla e posso uscire If nRKerfId = GDB_ID.NULL Then Return False EgtSetName(nRKerfId, NAME_KERF_REGION) EgtSetMode(nRKerfId, GDB_MD.HIDDEN) End If ' Box e baricentro della regione di kerf Dim b3Kerf As New BBox3d EgtGetBBoxGlob(nRKerfId, GDB_BB.STANDARD, b3Kerf) Dim ptKerfCen As Point3d EgtCentroid(nRKerfId, GDB_ID.ROOT, ptKerfCen) ' Eseguo ricerca If FindVacuumCupsOnRaw(nRawId, ptRawCen, b3Kerf, ptKerfCen, nKerfId, nRKerfId, rmData) Then Return True End If ' In caso di fallimento, provo riducendo con offset la regione di kerf ' (così si simula la proiezione del centro sul MAT - medial axis transform) Dim bOkFind As Boolean = False Dim vOffset() As Double = {-450, -350, -250, -150} For i As Integer = 0 To vOffset.Length() - 1 Dim nRKerfOffsId = EgtCopy(nRKerfId, nRKerfId, GDB_POS.AFTER) If EgtSurfFrOffset(nRKerfOffsId, vOffset(i), OFF_TYPE.FILLET) AndAlso EgtCentroid(nRKerfOffsId, GDB_ID.ROOT, ptKerfCen) Then Dim nOutOffsId As Integer = GetRegionOutLoop(nRKerfOffsId, nRawId) bOkFind = FindVacuumCupsOnRaw(nRawId, ptRawCen, b3Kerf, ptKerfCen, nOutOffsId, nRKerfId, rmData) EgtErase(nOutOffsId) End If EgtErase(nRKerfOffsId) If bOkFind Then Return True Next Return False End Function Friend Function PutVacuumCupsOnPart(nPartId As Integer, ByRef rmData As RawMoveData, ByRef b3Part As BBox3d) As Boolean ' Ripristino posizione originale ventose ResetVacuumCups() ' Verifico sia veramente un pezzo If EgtGetRawPartFromPart(nPartId) = GDB_ID.NULL Then Return False ' Recupero la regione del pezzo Dim nGrpRegId As Integer = EgtGetFirstNameInGroup(nPartId, NAME_REGION) Dim nRegId As Integer = EgtGetFirstInGroup(nGrpRegId) While nRegId <> GDB_ID.NULL If EgtGetType(nRegId) = GDB_TY.SRF_FRGN Then Exit While nRegId = EgtGetNext(nRegId) End While If nRegId = GDB_ID.NULL Then Return False ' Box e baricentro del pezzo (sempre sopra) EgtGetBBoxGlob(nRegId, GDB_BB.STANDARD, b3Part) Dim ptPartCen As Point3d EgtCentroid(nRegId, GDB_ID.ROOT, ptPartCen) ' Calcolo il contorno esterno del pezzo Dim nOutId As Integer = GetRegionOutLoop(nRegId, nGrpRegId) If nOutId = GDB_ID.NULL Then Return False ' Eseguo ricerca If FindVacuumCupsOnRaw(nPartId, ptPartCen, b3Part, ptPartCen, nOutId, nRegId, rmData) Then EgtErase(nOutId) Return True Else EgtErase(nOutId) End If ' In caso di fallimento, provo riducendo con offset la regione di kerf ' (così si simula la proiezione del centro sul MAT - medial axis transform) Dim bOkFind As Boolean = False Dim vOffset() As Double = {-450, -350, -250, -150} For i As Integer = 0 To vOffset.Length() - 1 Dim nRegOffsId As Integer = EgtCopy(nRegId, nRegId, GDB_POS.AFTER) Dim ptRegOffsCen As Point3d If EgtSurfFrOffset(nRegOffsId, vOffset(i), OFF_TYPE.FILLET) AndAlso EgtCentroid(nRegOffsId, GDB_ID.ROOT, ptRegOffsCen) Then Dim nOutOffsId As Integer = GetRegionOutLoop(nRegOffsId, nGrpRegId) bOkFind = FindVacuumCupsOnRaw(nPartId, ptRegOffsCen, b3Part, ptPartCen, nOutOffsId, nRegId, rmData) EgtErase(nOutOffsId) End If EgtErase(nRegOffsId) If bOkFind Then Return True Next Return False End Function Private Function FindVacuumCupsOnRaw(nRawId As Integer, ptRawCen As Point3d, b3Kerf As BBox3d, ptKerfCen As Point3d, nOutlineId As Integer, nRKerfId As Integer, ByRef rmData As RawMoveData) As Boolean ' Cerco migliore configurazione di ventose per prendere il grezzo Const MAX_SEL As Integer = 20 For nI As Integer = 1 To MAX_SEL ' Recupero la configurazione di ventose nI-esima Dim sCups() As String = Nothing Dim sCups2() As String = Nothing If Not GetVacuumCupSelection(nI, sCups, sCups2) Then Return False ' Determino validità soluzioni della configurazione Dim vtMove As New Vector3d Dim ptRotCen As New Point3d Dim dRotAngDeg As Double = 0 Dim vtMove2 As New Vector3d Dim ptRotCen2 As New Point3d Dim dRotAngDeg2 As Double = 0 Dim dDist = TestVacuumCupSelection(sCups, b3Kerf, ptKerfCen, nOutlineId, nRKerfId, vtMove, ptRotCen, dRotAngDeg) Dim dDist2 = TestVacuumCupSelection(sCups2, b3Kerf, ptKerfCen, nOutlineId, nRKerfId, vtMove2, ptRotCen2, dRotAngDeg2) If dDist > INFINITO - 1 And dDist2 > INFINITO - 1 Then Continue For If dDist2 < dDist Then sCups = sCups2 vtMove = vtMove2 ptRotCen = ptRotCen2 dRotAngDeg = dRotAngDeg2 End If ' Eseguo il movimento EgtMove(m_nVacId, vtMove, GDB_RT.GLOB) EgtRotate(m_nVacId, ptRotCen, Vector3d.Z_AX(), dRotAngDeg, GDB_RT.GLOB) ' Visualizzo le ventose For nJ As Integer = 0 To sCups.Length() - 1 Dim nCupId = EgtGetFirstNameInGroup(m_nVacId, sCups(nJ)) EgtSetStatus(nCupId, GDB_ST.ON_) Next ' Calcolo delta posizione Dim frCurrRef As New Frame3d EgtFrame(m_nRefId, GDB_ID.ROOT, frCurrRef) Dim vtDelta As Vector3d = frCurrRef.Orig() - ptRawCen ' Assegno dati noti al movimento del grezzo rmData.m_nId = nRawId rmData.m_vtRawMove = Vector3d.NULL() rmData.m_vtDelta = vtDelta rmData.m_dAngRotDeg = dRotAngDeg Dim sVal As String = String.Empty For Each sCup As String In sCups If String.IsNullOrEmpty(sVal) Then sVal &= sCup Else sVal &= "," & sCup End If Next rmData.m_sCups = sVal Return True Next Return False End Function Private Function GetVacuumCupSelection(nInd As Integer, ByRef sCups() As String, ByRef sCups2() As String) As Boolean ' Recupero elenco ventose nella soluzione Dim sSel As String = "Sel" & nInd.ToString() Dim sVal As String = String.Empty If Not EgtGetInfo(m_nVacId, sSel, sVal) Then Return False If sVal.IndexOf("/") >= 0 Then Dim sSplit() As String = sVal.Split("/".ToCharArray) If sSplit.Length() >= 2 Then sCups = sSplit(0).Split(",".ToCharArray) sCups2 = sSplit(1).Split(",".ToCharArray) ElseIf sSplit.Length() >= 1 Then sCups = sSplit(0).Split(",".ToCharArray) sCups2 = Nothing Else sCups = Nothing sCups2 = Nothing End If Else sCups = sVal.Split(",".ToCharArray) sCups2 = Nothing End If Return True End Function Private Function GetVacRotAxisSteps(ByRef vAngRot As List(Of Double)) As Boolean ' Recupero l'asse rotante della testa ventosa Dim nRotAxId As Integer = EgtGetParent(EgtGetHeadId(VACUUM_HEAD)) ' Verifico se contiene info con STEPS Dim sSteps As String = "" If Not EgtGetInfo(nRotAxId, KEY_ROTVAC_STEPS, sSteps) Then Return False ' Leggo gli step previsti Dim vStep() As String = sSteps.Split(",".ToCharArray) For Each sStep As String In vStep Dim dStep As Double = 0 If StringToDouble(sStep, dStep) Then vAngRot.Add(dStep) End If Next Return True End Function Private Function TestVacuumCupSelection(sCups() As String, b3Raw As BBox3d, ptRawCen As Point3d, nOutlineId As Integer, nRawRegId As Integer, ByRef vtMove As Vector3d, ByRef ptRotCen As Point3d, ByRef dRotAngDeg As Double) As Double ' Se definizione mancante, scarto soluzione If IsNothing(sCups) Then Return INFINITO ' Ne calcolo il box Dim b3Vac As New BBox3d For nJ As Integer = 0 To sCups.Length() - 1 Dim nCupId = EgtGetFirstNameInGroup(m_nVacId, sCups(nJ)) Dim b3Cup As New BBox3d If EgtGetBBoxGlob(nCupId, GDB_BB.STANDARD, b3Cup) Then b3Vac.Add(b3Cup) Next If b3Vac.IsEmpty() Then Return INFINITO ' Se box maggiore di quello del pezzo, scarto soluzione If b3Vac.Radius() > b3Raw.Radius() Then Return INFINITO ' Determino il movimento vtMove = ptRawCen - b3Vac.Center() b3Vac.Move(vtMove) ' Determino la rotazione, allineando il lato lungo delle ventose con quello del grezzo ptRotCen = b3Vac.Center() Dim frMinRect As New Frame3d If EgtCurveMinAreaRectangleXY(nOutlineId, GDB_ID.ROOT, frMinRect) Then Dim dLen, dAngVertDeg, dAngOrizzDeg As Double frMinRect.VersX().ToSpherical(dLen, dAngVertDeg, dAngOrizzDeg) dRotAngDeg = dAngOrizzDeg If b3Vac.DimY() > b3Vac.DimX() + EPS_SMALL Then dRotAngDeg -= 90 While dRotAngDeg >= 90 dRotAngDeg -= 180 End While While dRotAngDeg < -90 dRotAngDeg += 180 End While Else dRotAngDeg = 0 If (b3Vac.DimX() >= b3Vac.DimY() And b3Raw.DimX() < b3Raw.DimY()) Or (b3Vac.DimX() < b3Vac.DimY() And b3Raw.DimX() >= b3Raw.DimY()) Then dRotAngDeg = -90 End If End If ' Identificativi delle ventose Dim nCups(sCups.Length() - 1) As Integer For nJ As Integer = 0 To sCups.Length() - 1 nCups(nJ) = EgtGetFirstNameInGroup(m_nVacId, sCups(nJ)) Next ' Angoli di prova Dim vAngRot As New List(Of Double) ' Se asse rotante ventosa a step If GetVacRotAxisSteps(vAngRot) Then ' Ordino secondo distanza angolare crescente da direzione di allineamento (modulo 180 deg) Dim dRotRefDeg As Double = dRotAngDeg vAngRot.Sort(Function(P, Q) Dim dDiffP = Math.Abs( P - dRotRefDeg) If Math.Abs( dDiffP - 180) < 10 * EPS_ANG_SMALL Then dDiffP = 1 Dim dDiffQ = Math.Abs( Q - dRotRefDeg) If Math.Abs( dDiffQ - 180) < 10 * EPS_ANG_SMALL Then dDiffQ = 1 Return ( dDiffP - dDiffQ) End Function) ' Annullo la rotazione di allineamento dRotAngDeg = 0 ' altrimenti in continuo Else ' Assegno più valori di ricerca e conservo angolo di allineamento vAngRot.AddRange({0, +5, -5, +12.5, -12.5, +25, -25, +45, -45}) End If ' Eseguo verifica delle ventose rispetto al grezzo Dim bVacOk As Boolean = False For i As Integer = 0 To vAngRot.Count() - 1 If TestVacuumCups(nCups, nRawRegId, vtMove, ptRotCen, dRotAngDeg + vAngRot(i)) Then dRotAngDeg += vAngRot(i) bVacOk = True Exit For End If Next If Not bVacOk Then Return INFINITO ' Recupero riferimento della testa ventose Dim frCurrRef As New Frame3d EgtFrame(m_nRefId, GDB_ID.ROOT, frCurrRef) Dim ptRef As Point3d = frCurrRef.Orig() ' Applico movimento e rotazione al punto ptRef.Move(vtMove) ptRef.Rotate(ptRotCen, Vector3d.Z_AX(), dRotAngDeg) ' Ne calcolo la distanza dal centro della tavola Dim b3Tab As New BBox3d EgtGetTableArea(1, b3Tab) Dim dDist As Double = Point3d.DistXY(ptRef, b3Tab.Center()) Return dDist End Function Private Function TestVacuumCups(nCups() As Integer, nRawRegId As Integer, vtMove As Vector3d, ptRotCen As Point3d, dRotAngDeg As Double) As Boolean ' Eseguo verifica delle ventose rispetto al grezzo Dim bVacOk As Boolean = True For nJ As Integer = 0 To nCups.Length() - 1 Dim nCupId = nCups(nJ) ' Eseguo rototraslazione delle ventose per verificare se sono contenute nel grezzo EgtMove(nCupId, vtMove, GDB_RT.GLOB) EgtRotate(nCupId, ptRotCen, Vector3d.Z_AX(), dRotAngDeg, GDB_RT.GLOB) ' Confronto le regioni If EgtSurfFrChunkSimpleClassify(nRawRegId, 0, nCupId, 0) <> REGC.IN2 Then bVacOk = False ' Annullo rototraslazione EgtRotate(nCupId, ptRotCen, Vector3d.Z_AX(), -dRotAngDeg, GDB_RT.GLOB) EgtMove(nCupId, -vtMove, GDB_RT.GLOB) ' Se verifica fallita, esco dal ciclo If Not bVacOk Then Exit For Next Return bVacOk End Function Friend Function SaveOneMoveInfo(nId As Integer, rmData As RawMoveData) As Boolean ' Assegno le informazioni EgtSetInfo(nId, "Id", rmData.m_nId) EgtSetInfo(nId, "Mv", rmData.m_vtRawMove) EgtSetInfo(nId, "Rr", rmData.m_dRawAngRotDeg) EgtSetInfo(nId, "Dt", rmData.m_vtDelta) EgtSetInfo(nId, "Ad", rmData.m_dAngRotDeg) EgtSetInfo(nId, "Vc", rmData.m_sCups) EgtSetInfo(nId, "Vt", GetVacuumType()) Return True End Function Friend Function RemoveOneMoveInfo(nId As Integer) As Boolean ' Rimuovo le informazioni EgtRemoveInfo(nId, "Id") EgtRemoveInfo(nId, "Mv") EgtRemoveInfo(nId, "Rr") EgtRemoveInfo(nId, "Dt") EgtRemoveInfo(nId, "Ad") EgtRemoveInfo(nId, "Vc") EgtRemoveInfo(nId, "Vt") Return True End Function Friend Function SaveOneMoveInfoInDisposition(nDispId As Integer, rmData As RawMoveData) As Boolean ' Se movimento e rotazione trascurabili, inutile salvare If rmData.m_vtRawMove.IsSmall() AndAlso Math.Abs(rmData.m_dRawAngRotDeg) < EPS_ANG_SMALL Then Return True ' Creo il gruppo Dim nRpmId As Integer = EgtCreateGroup(nDispId) If nRpmId = GDB_ID.NULL Then Return False EgtSetName(nRpmId, "Rpm" & rmData.m_nId.ToString()) ' Assegno le informazioni SaveOneMoveInfo(nRpmId, rmData) Return True End Function Friend Function SaveMoveInfoInDisposition(nDispId As Integer, rmList As List(Of RawMoveData)) As Boolean ' Verifico DispId If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False ' aggiungo al gruppo disposizione dei sottogruppi con i dati di movimento dei grezzi spostati For Each rmData As RawMoveData In rmList If Not SaveOneMoveInfoInDisposition(nDispId, rmData) Then Return False Next Return True End Function Friend Function GetMoveInfoInDisposition(nDispId As Integer, ByRef rmList As List(Of RawMoveData)) As Boolean ' Verifico DispId If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False ' Recupero i gruppi con i dati Dim nRpmId As Integer = EgtGetFirstNameInGroup(nDispId, "Rpm*") While nRpmId <> GDB_ID.NULL ' Recupero le informazioni Dim rmData As New RawMoveData EgtGetInfo(nRpmId, "Id", rmData.m_nId) EgtGetInfo(nRpmId, "Mv", rmData.m_vtRawMove) EgtGetInfo(nRpmId, "Rr", rmData.m_dRawAngRotDeg) EgtGetInfo(nRpmId, "Dt", rmData.m_vtDelta) EgtGetInfo(nRpmId, "Ad", rmData.m_dAngRotDeg) EgtGetInfo(nRpmId, "Vc", rmData.m_sCups) EgtGetInfo(nRpmId, "Vt", GetVacuumType()) ' se non già presenti, le inserisco nella lista If FindRawMoveData(rmData.m_nId, rmList) = -1 Then rmList.Add(rmData) End If ' Cerco un altro gruppo nRpmId = EgtGetNextName(nRpmId, "Rpm*") End While Return True End Function Friend Function FindRawMoveData(nRawId As Integer, ByRef rmList As List(Of RawMoveData)) As Integer ' Cerco in lista record con dati del grezzo indicato Dim nInd As Integer = -1 For i As Integer = 0 To rmList.Count() - 1 If rmList(i).m_nId = nRawId Then nInd = i Exit For End If Next Return nInd End Function Private Function AddRawMoveData(nRawId As Integer, ByRef rmList As List(Of RawMoveData)) As Integer ' Cerco in lista record con dati del grezzo indicato Dim nInd As Integer = -1 For i As Integer = 0 To rmList.Count() - 1 If rmList(i).m_nId = nRawId Then nInd = i Exit For End If Next ' Se trovato If nInd <> -1 Then ' Se con movimenti trascurabili e non alla fine, lo sposto alla fine If rmList(nInd).m_vtRawMove.IsSmall() AndAlso Math.Abs(rmList(nInd).m_dRawAngRotDeg) < EPS_ANG_SMALL AndAlso nInd <> rmList.Count() - 1 Then rmList.Add(rmList(nInd)) rmList.RemoveAt(nInd) nInd = rmList.Count() - 1 End If ' Se non trovato, lo accodo Else rmList.Add(New RawMoveData(nRawId)) nInd = rmList.Count() - 1 End If Return nInd End Function Friend Function AddRawMoveData(nRawId As Integer, vtMove As Vector3d, ByRef rmList As List(Of RawMoveData)) As Integer ' Recupero o creo record con dati del grezzo indicato Dim nInd As Integer = AddRawMoveData(nRawId, rmList) If nInd = -1 Then Return -1 ' Aggiorno i valori rmList(nInd).m_vtRawMove += vtMove Return nInd End Function Friend Function AddRawMoveData(nRawId As Integer, dRawAngRotDeg As Double, ByRef rmList As List(Of RawMoveData)) As Integer ' Recupero o creo record con dati del grezzo indicato Dim nInd As Integer = AddRawMoveData(nRawId, rmList) If nInd = -1 Then Return -1 ' Aggiorno i valori rmList(nInd).m_dRawAngRotDeg += dRawAngRotDeg Return nInd End Function Friend Function AddRawMoveData(rmData As RawMoveData, ByRef rmList As List(Of RawMoveData)) As Integer ' Recupero o creo record con dati del grezzo indicato Dim nInd As Integer = AddRawMoveData(rmData.m_nId, rmList) If nInd = -1 Then Return -1 ' Aggiorno i valori (tengo conto di quanto già ruotato il pezzo) Dim vtDeltaRot As New Vector3d(rmData.m_vtDelta) vtDeltaRot.Rotate(Vector3d.Z_AX(), -rmList(nInd).m_dRawAngRotDeg) rmList(nInd).m_vtDelta = vtDeltaRot rmList(nInd).m_dAngRotDeg = rmData.m_dAngRotDeg - rmList(nInd).m_dRawAngRotDeg rmList(nInd).m_sCups = rmData.m_sCups Return nInd End Function Friend Sub RemoveRawMoveData(nRawId As Integer, ByRef rmList As List(Of RawMoveData)) ' Cerco in lista record con dati del grezzo indicato Dim nInd As Integer = -1 For i As Integer = 0 To rmList.Count() - 1 If rmList(i).m_nId = nRawId Then nInd = i Exit For End If Next ' Se trovato, lo elimino If nInd >= 0 Then rmList.RemoveAt(nInd) End If End Sub Friend Function SaveRemoveByHandInDisposition(nDispId As Integer, bRemoveByHand As Boolean) As Boolean ' Verifico DispId If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False ' Imposto flag EgtSetInfo(nDispId, "Rbh", bRemoveByHand) Return True End Function Friend Function GetRemoveByHandInDisposition(nDispId As Integer) As Boolean ' Verifico DispId If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False ' Leggo flag Dim bRemoveByHand As Boolean = False EgtGetInfo(nDispId, "Rbh", bRemoveByHand) Return bRemoveByHand End Function End Module