Imports EgtUILib Public NotInheritable Class DispositionUtility Friend Const MOBILE As String = "MOBILE" Friend Const MDIR As String = "MDir" Friend Const STROKE As String = "Stroke" Friend Const POS As String = "Val" Friend Const PDIST As String = "PDist" Friend Const MDIST As String = "MDist" Friend Const HOOK As String = "HOOK" Friend Const CLASS_ As String = "CLASS" Friend Const USED As String = "USED" Friend Const FIXED As String = "FIXED" Friend Const TYPE As String = "TYPE" Friend Const FREE As String = "FREE" Friend Const LINE As String = "LINE" Friend Const POINT As String = "POINT" Friend Enum HOOKTYPE As Integer FREE = 0 POINT = 1 LINE = 2 End Enum Friend Shared m_vtHook As Vector3d = Vector3d.NULL Friend Shared m_nUsedHookId As Integer = GDB_ID.NULL Friend Shared m_nPrevUsedHookId As Integer = GDB_ID.NULL ' Identificativi per elemento da selezionare/deselezionare Friend Enum SelType As Integer NULL = 0 FIXTURE = 1 RAWPART = 2 BARS = 3 PART = 4 End Enum Friend Shared Function GetRawPartRefPoint(nRawPartId As Integer, RawRefPosition As MCH_CR) As Point3d Dim bboxRawPart As New BBox3d ' recupero il solido del grezzo dal primo elemento selezionato Dim nRawSolidId As Integer = EgtGetFirstNameInGroup(nRawPartId, RAWSOLID) ' ne calcolo il BBox EgtGetBBoxGlob(nRawSolidId, GDB_BB.ONLY_VISIBLE, bboxRawPart) ' imposto il riferimento della tavola Dim ptTableRef As Point3d EgtGetTableRef(1, ptTableRef) ' calcolo i punti min e max del bbox riferiti alla tavola Dim ptBBoxRawPartMin As New Point3d(bboxRawPart.Min) Dim ptBBoxRawPartMax As New Point3d(bboxRawPart.Max) ptBBoxRawPartMin.ToLoc(New Frame3d(ptTableRef)) ptBBoxRawPartMax.ToLoc(New Frame3d(ptTableRef)) ' dal box e dal tipo di punto di riferimento selezionato ricavo le coordinate del punto di riferimento Dim ptRawRefPoint As Point3d Select Case RawRefPosition Case MCH_CR.TL ptRawRefPoint.x = ptBBoxRawPartMin.x ptRawRefPoint.y = ptBBoxRawPartMax.y Case MCH_CR.TR ptRawRefPoint.x = ptBBoxRawPartMax.x ptRawRefPoint.y = ptBBoxRawPartMax.y Case MCH_CR.BL ptRawRefPoint.x = ptBBoxRawPartMin.x ptRawRefPoint.y = ptBBoxRawPartMin.y Case MCH_CR.BR ptRawRefPoint.x = ptBBoxRawPartMax.x ptRawRefPoint.y = ptBBoxRawPartMin.y End Select ptRawRefPoint.z = ptBBoxRawPartMin.z Return ptRawRefPoint End Function Public Shared Function MoveRawPartPartAndFixture(nMoveId As Integer, vtMove As Vector3d, sSelType As Integer, Optional ptCurr As Point3d = Nothing, Optional nCount As Integer = 1) As Boolean Dim bErrorMoving As Boolean = False ' Muovo gli oggetti selezionati se consentito If nMoveId = GDB_ID.SEL Then Dim nSelObjId As Integer = EgtGetFirstSelectedObj() While nSelObjId <> GDB_ID.NULL If EgtVerifyFixture(nSelObjId) Then If Not EgtMoveFixture(nSelObjId, vtMove) Then bErrorMoving = True nSelObjId = EgtGetPrevSelectedObj() While nSelObjId <> GDB_ID.NULL If EgtVerifyFixture(nSelObjId) Then EgtMoveFixture(nSelObjId, -vtMove) Else EgtMoveRawPart(nSelObjId, -vtMove) End If nSelObjId = EgtGetPrevSelectedObj() End While Exit While End If nSelObjId = EgtGetNextSelectedObj() Else If Not EgtMoveRawPart(nSelObjId, vtMove) Then bErrorMoving = True nSelObjId = EgtGetPrevSelectedObj() While nSelObjId <> GDB_ID.NULL If EgtVerifyFixture(nSelObjId) Then EgtMoveFixture(nSelObjId, -vtMove) Else EgtMoveRawPart(nSelObjId, -vtMove) End If nSelObjId = EgtGetPrevSelectedObj() End While Exit While End If nSelObjId = EgtGetNextSelectedObj() End If End While Else Dim sName As String = "" EgtGetName(EgtGetParent(nMoveId), sName) If EgtVerifyFixture(nMoveId) Then VerifyHookFixture(nMoveId, vtMove, ptCurr, True) If Not EgtMoveFixture(nMoveId, vtMove) Then bErrorMoving = True End If ElseIf sSelType = SelType.BARS Then VerifyBarPosition(nMoveId, vtMove) Else If Not EgtMoveRawPart(nMoveId, vtMove) Then bErrorMoving = True End If End If End If ' Variabile che contiene l'eventuale spostamento correttivo per interferenza con riferimenti Dim vtRefMove As New Vector3d(Vector3d.NULL) ' Se non ci sono stati errori nel movimento Dim bErrorVerify As Boolean = False If Not bErrorMoving Then ' Verifico che gli spostamenti effettuati siano validi If nMoveId = GDB_ID.SEL Then Dim nSelObjId As Integer = EgtGetFirstSelectedObj() While nSelObjId <> GDB_ID.NULL If Not VerifyRawPartFixturePos(nSelObjId, vtMove, vtRefMove) Then bErrorVerify = True Exit While End If nSelObjId = EgtGetNextSelectedObj() End While Else If Not VerifyRawPartFixturePos(nMoveId, vtMove, vtRefMove) Then bErrorVerify = True End If 'Dim sOut As String = "VerifyRaw : Count=" & nCount & " Err=" & If(bErrorVerify, "1", "0") & ' " Move=" & LenToString(vtMove.x, 3) & "," & LenToString(vtMove.y, 3) & ' " RefMove=" & LenToString(vtRefMove.x, 3) & "," & LenToString(vtRefMove.y, 3) 'EgtOutLog(sOut) End If End If ' Se non c'è errore ma necessaria correzione riferimento If Not bErrorVerify AndAlso Not vtRefMove.IsSmall() Then ' provo a correggere (max 1 prova) If nCount < 2 Then bErrorVerify = Not MoveRawPartPartAndFixture(nMoveId, vtRefMove, DispositionUtility.SelType.NULL, Nothing, nCount + 1) End If End If ' Se c'è almeno uno spostamento non valido If bErrorVerify Then ' ripristino la situazione iniziale annullando tutti i movimenti If nMoveId = GDB_ID.SEL Then Dim nSelObjId As Integer = EgtGetFirstSelectedObj() While nSelObjId <> GDB_ID.NULL If EgtVerifyFixture(nSelObjId) Then EgtMoveFixture(nSelObjId, -vtMove) Else EgtMoveRawPart(nSelObjId, -vtMove) End If nSelObjId = EgtGetNextSelectedObj() End While Else If EgtVerifyFixture(nMoveId) Then EgtMoveFixture(nMoveId, -vtMove) ' segno hook occupato prima del movimento correttivo come non utilizzato SetHookUsed(m_nPrevUsedHookId, nMoveId, True) 'EgtSetInfo(m_nPrevUsedHookId, USED, nMoveId) SetHookUsed(m_nPrevUsedHookId, nMoveId, False) 'EgtRemoveInfo(m_nUsedHookId, USED) Else EgtMoveRawPart(nMoveId, -vtMove) End If End If ' ritorno falso Return False End If Return True End Function Public Shared Function VerifyRawPartFixturePos(nMovedObjId As Integer, ByRef vtOrigMove As Vector3d, ByRef vtRefMove As Vector3d) As Boolean ' Verifico quale sia il tipo dell'oggetto mosso If EgtVerifyFixture(nMovedObjId) Then Return VerifyFixturePosition(nMovedObjId, vtRefMove) ElseIf EgtVerifyRawPartCurrPhase(nMovedObjId) Then Return VerifyRawPosition(nMovedObjId, vtOrigMove, vtRefMove) Else Return False End If End Function Friend Shared Function VerifyFixturePosition(nMovedFixtureId As Integer, ByRef vtRefMove As Vector3d) As Boolean ' Definisco il box della ventosa mossa Dim bboxMovedFixture As New BBox3d EgtGetBBoxGlob(nMovedFixtureId, GDB_BB.ONLY_VISIBLE, bboxMovedFixture) Dim bboxFixture As New BBox3d ' Ciclo sui sottopezzi correnti per verificare le collisioni con il sottopezzo spostato Dim nFixtureId As Integer = EgtGetFirstFixture() While nFixtureId <> GDB_ID.NULL If EgtVerifyFixture(nFixtureId) AndAlso nFixtureId <> nMovedFixtureId Then ' ne calcolo il BBox EgtGetBBoxGlob(nFixtureId, GDB_BB.ONLY_VISIBLE, bboxFixture) ' verifico se c'è sovrapposizione If bboxMovedFixture.OverlapsXY(bboxFixture) Then ' se c'è restituisco falso perchè i sottopezzi non si possono sovrapporre Return False End If End If nFixtureId = EgtGetNextFixture(nFixtureId) End While Return VerifyFixtureWithRaw(nMovedFixtureId, vtRefMove) End Function Private Shared Function VerifyFixtureWithRaw(nFixtureId As Integer, ByRef vtRefMove As Vector3d) As Boolean ' Tengo da parte il riferimento della tavola Dim ptTableRef As Point3d EgtGetTableRef(1, ptTableRef) Dim TableFrame As New Frame3d(ptTableRef) ' Definisco il box del sottopezzo mosso Dim bboxFixture As New BBox3d EgtGetBBoxGlob(nFixtureId, GDB_BB.ONLY_VISIBLE, bboxFixture) Dim bboxRawPart As New BBox3d ' Variabile che indica se il riferimento non è in battuta su nessun grezzo Dim bRefAttachedToRaw As Boolean = False ' Ciclo sui grezzi della fase corrente per verificare le collisioni con il sottopezzo mosso Dim nRawPartId As Integer = EgtGetFirstRawPart() While nRawPartId <> GDB_ID.NULL If EgtVerifyRawPartCurrPhase(nRawPartId) Then ' recupero il solido del grezzo Dim nRawSolidId As Integer = EgtGetFirstNameInGroup(nRawPartId, RAWSOLID) ' ne calcolo il BBox EgtGetBBoxGlob(nRawSolidId, GDB_BB.ONLY_VISIBLE, bboxRawPart) ' verifico il tipo di sottopezzo Select Case FixtureType(nFixtureId) ' se il sottopezzo è una ventosa Case FIX_TYPE.VACUUM ' verifico se c'è sovrapposizione If bboxFixture.OverlapsXY(bboxRawPart) Then ' se c'è devo verificare che l'altezza del grezzo sia uguale a quella della ventosa ' recupero altezza ventosa Dim dFixtureHeight As Double = 0 EgtGetInfo(nFixtureId, "H", dFixtureHeight) ' recupero altezza grezzo riferita alla tavola Dim dRawPartMin As Point3d = bboxRawPart.Min dRawPartMin.ToLoc(TableFrame) ' se l'altezza grezzo è minore di quella della ventosa, lo sposto alla stessa altezza If dRawPartMin.z < dFixtureHeight - EPS_SMALL Then Dim vtMove As New Vector3d(0, 0, dFixtureHeight - dRawPartMin.z) EgtMoveRawPart(nRawPartId, vtMove) ' ricalcolo il BBox del solido del grezzo per averlo aggiornato con la nuova Z EgtGetBBoxGlob(nRawSolidId, GDB_BB.ONLY_VISIBLE, bboxRawPart) End If ' se non c'è sovrapposizione devo verificare il grezzo con tutti gli altri sottopezzi per sapere se ho tolto l'ultimo e quindi devo abbassarlo Else ' variabile che contiene la massima altezza delle ventose sottostanti Dim dMaxFixtureHeight As Double = 0 ' Variabile che dice se c'è almeno una ventosa sotto il grezzo Dim bIsFixtureUnderRawPart As Boolean = False Dim nOtherFixtureId As Integer = EgtGetFirstFixture() While nOtherFixtureId <> GDB_ID.NULL ' evito di rifare la verifica sul sottopezzo mosso If nOtherFixtureId <> nFixtureId Then ' calcolo il BBox del sottopezzo Dim bboxOtherFixture As New BBox3d EgtGetBBoxGlob(nOtherFixtureId, GDB_BB.ONLY_VISIBLE, bboxOtherFixture) If bboxRawPart.OverlapsXY(bboxOtherFixture) Then bIsFixtureUnderRawPart = True ' recupero altezza ventosa Dim dOtherFixtureHeight As Double = 0 EgtGetInfo(nFixtureId, "H", dOtherFixtureHeight) ' la confronto con quella massima If dOtherFixtureHeight > dMaxFixtureHeight Then dMaxFixtureHeight = dOtherFixtureHeight End If End If End If nOtherFixtureId = EgtGetNextFixture(nOtherFixtureId) End While ' recupero altezza grezzo riferita alla tavola Dim dRawPartMin As Point3d = bboxRawPart.Min dRawPartMin.ToLoc(TableFrame) ' se non ci sono ventose sotto il grezzo If Not bIsFixtureUnderRawPart Then ' verifico che il grezzo sia ad altezza tavola If dRawPartMin.z <> 0 Then Dim vtMove As New Vector3d(0, 0, -dRawPartMin.z) EgtMoveRawPart(nRawPartId, vtMove) End If Else ' se ci sono verifico che l'altezza del grezzo sia quella della ventosa più alta If Math.Abs(dRawPartMin.z - dMaxFixtureHeight) > EPS_SMALL Then Dim vtMove As New Vector3d(0, 0, dMaxFixtureHeight - dRawPartMin.z) EgtMoveRawPart(nRawPartId, vtMove) End If End If End If ' se il sottopezzo è un riferimento Case FIX_TYPE.REFERENCE ' verifico se c'è sovrapposizione If bboxFixture.OverlapsXY(bboxRawPart) Then ' recupero arco del riferimento Dim arcRefId As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_ARC) ' calcolo bbox dell'arco di riferimento Dim bboxArcRef As New BBox3d EgtGetBBoxGlob(arcRefId, GDB_BB.STANDARD, bboxArcRef) ' ne faccio l'offset ?? 'bboxArcRef.Expand(10) If bboxRawPart.OverlapsXY(bboxArcRef) Then ' recupero contorno del grezzo Dim ccompoRawPartOutlineId As Integer = EgtGetFirstNameInGroup(nRawPartId, RAWOUTLINE) 'recupero il raggio dell'arco di riferimento Dim dArcRadius As Double EgtArcRadius(arcRefId, dArcRadius) ' faccio copia e offset del contorno grezzo Dim ccompoRawPartOutlineOffsetId As Integer = EgtCopyGlob(ccompoRawPartOutlineId, ccompoRawPartOutlineId, GDB_POS.AFTER) EgtOffsetCurve(ccompoRawPartOutlineOffsetId, dArcRadius, OFF_TYPE.FILLET) ' recupero centro dell'arco di riferimento Dim ptArcCenter As Point3d EgtCenterPoint(arcRefId, ccompoRawPartOutlineOffsetId, ptArcCenter) ' verifico quale è il punto dell'offset vicino al centro dell'arco di riferimento Dim dDist As Double Dim ptMin As Point3d Dim nSide As Integer EgtPointCurveDistSide(ptArcCenter, ccompoRawPartOutlineOffsetId, Vector3d.Z_AX, ccompoRawPartOutlineOffsetId, dDist, ptMin, nSide) ' cancello offset EgtErase(ccompoRawPartOutlineOffsetId) ' calcolo il vettore di spostamento necessario ad allinearli Dim vtDelta As Vector3d = ptArcCenter - ptMin vtDelta.z = 0 ' se i punti coincidono, esco If vtDelta.IsSmall() Then ' il grezzo è in battuta sul riferimento Dim nContactColDisk As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_DISK) EgtSetColor(nContactColDisk, ReferenceContactColGreen) bRefAttachedToRaw = True Else ' altrimenti riporto il vettore di correzione vtRefMove = -vtDelta.Glob(ccompoRawPartOutlineId) End If Else ' il grezzo non è in battuta sul riferimento Dim nContactColDisk As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_DISK) EgtSetColor(nContactColDisk, ReferenceContactColRed) End If End If End Select End If nRawPartId = EgtGetNextRawPart(nRawPartId) End While ' se è un riferimento e non è in battuta sul nessun grezzo If FixtureType(nFixtureId) = FIX_TYPE.REFERENCE AndAlso Not bRefAttachedToRaw Then ' lo segnalo Dim nContactColDisk As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_DISK) EgtSetColor(nContactColDisk, ReferenceContactColRed) End If Return True End Function Friend Shared Function VerifyRawPosition(nMovedRawId As Integer, ByRef vtOrigMove As Vector3d, ByRef vtRefMove As Vector3d) As Boolean ' Recupero il solido del grezzo Dim nMovedRawSolidId As Integer = EgtGetFirstNameInGroup(nMovedRawId, RAWSOLID) ' definisco il box del solido del grezzo Dim bboxMovedRawPart As New BBox3d EgtGetBBoxGlob(nMovedRawSolidId, GDB_BB.ONLY_VISIBLE, bboxMovedRawPart) Dim bboxRawPart As New BBox3d ' Ciclo sui grezzi della fase corrente per verificare le collisioni con il grezzo spostato Dim nRawPartId As Integer = EgtGetFirstRawPart() While nRawPartId <> GDB_ID.NULL If EgtVerifyRawPartCurrPhase(nRawPartId) AndAlso nRawPartId <> nMovedRawId Then ' recupero il solido del grezzo Dim nRawSolidId As Integer = EgtGetFirstNameInGroup(nRawPartId, RAWSOLID) ' ne calcolo il BBox EgtGetBBoxGlob(nRawSolidId, GDB_BB.ONLY_VISIBLE, bboxRawPart) ' verifico se c'è sovrapposizione If bboxMovedRawPart.OverlapsXY(bboxRawPart) Then ' se c'è restituisco falso perchè i grezzi non si possono sovrapporre Return False End If End If nRawPartId = EgtGetNextRawPart(nRawPartId) End While ' verifico le interferenze tra il grezzo spostato e le ventose Return VerifyRawWithFixture(nMovedRawId, vtOrigMove, vtRefMove) End Function Private Shared Function VerifyRawWithFixture(nRawId As Integer, ByRef vtOrigMove As Vector3d, ByRef vtRefMove As Vector3d) As Boolean ' Tengo da parte il riferimento della tavola Dim ptTableRef As Point3d EgtGetTableRef(1, ptTableRef) Dim TableFrame As New Frame3d(ptTableRef) ' Recupero il solido del grezzo Dim nMovedRawSolidId As Integer = EgtGetFirstNameInGroup(nRawId, RAWSOLID) ' definisco il box del solido del grezzo Dim bboxRawPartId As New BBox3d EgtGetBBoxGlob(nMovedRawSolidId, GDB_BB.ONLY_VISIBLE, bboxRawPartId) ' Variabile che dice se c'è almeno una ventosa sotto il grezzo Dim bIsFixtureUnderRawPart As Boolean = False Dim bboxFixture As New BBox3d ' variabile che contiene la massima altezza delle ventose sottostanti Dim dMaxFixtureHeight As Double = 0 ' recupero altezza grezzo riferita alla tavola Dim dRawPartMin As Point3d = bboxRawPartId.Min dRawPartMin.ToLoc(TableFrame) ' Ciclo sui sottopezzi presenti per verificare le collisioni con il grezzo Dim nFixtureId As Integer = EgtGetFirstFixture() While nFixtureId <> GDB_ID.NULL ' calcolo il BBox del sottopezzo EgtGetBBoxGlob(nFixtureId, GDB_BB.ONLY_VISIBLE, bboxFixture) ' verifico se c'è sovrapposizione If bboxRawPartId.OverlapsXY(bboxFixture) Then Select Case FixtureType(nFixtureId) ' se il sottopezzo è una ventosa Case FIX_TYPE.VACUUM ' recupero altezza ventosa Dim dFixtureHeight As Double = 0 EgtGetInfo(nFixtureId, "H", dFixtureHeight) ' la confronto con quella massima If dFixtureHeight > dMaxFixtureHeight Then dMaxFixtureHeight = dFixtureHeight End If ' se l'altezza grezzo è diversa da quella della ventosa, lo sposto alla stessa altezza If dRawPartMin.z < dFixtureHeight - EPS_SMALL Then Dim vtMove As New Vector3d(0, 0, dFixtureHeight - dRawPartMin.z) EgtMoveRawPart(nRawId, vtMove) ' recupero il solido del grezzo Dim nRawSolidId As Integer = EgtGetFirstNameInGroup(nRawId, RAWSOLID) ' ricalcolo il BBox del solido del grezzo per averlo aggiornato con la nuova Z EgtGetBBoxGlob(nRawSolidId, GDB_BB.ONLY_VISIBLE, bboxRawPartId) dRawPartMin = bboxRawPartId.Min dRawPartMin.ToLoc(TableFrame) End If bIsFixtureUnderRawPart = True ' se il sottopezzo è un riferimento Case FIX_TYPE.REFERENCE ' recupero arco del riferimento Dim arcRefId As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_ARC) ' calcolo bbox dell'arco di riferimento Dim bboxArcRef As New BBox3d EgtGetBBoxGlob(arcRefId, GDB_BB.STANDARD, bboxArcRef) ' ne faccio l'offset ?? 'bboxArcRef.Expand(10) If bboxRawPartId.OverlapsXY(bboxArcRef) Then ' recupero contorno del grezzo Dim ccompoRawPartOutlineId As Integer = EgtGetFirstNameInGroup(nRawId, RAWOUTLINE) 'recupero il raggio dell'arco di riferimento Dim dArcRadius As Double EgtArcRadius(arcRefId, dArcRadius) ' faccio copia e offset del contorno grezzo Dim ccompoRawPartOutlineOffsetId As Integer = EgtCopyGlob(ccompoRawPartOutlineId, ccompoRawPartOutlineId, GDB_POS.AFTER) EgtOffsetCurve(ccompoRawPartOutlineOffsetId, dArcRadius, OFF_TYPE.FILLET) ' recupero centro dell'arco di riferimento Dim ptArcCenter As Point3d EgtCenterPoint(arcRefId, ccompoRawPartOutlineId, ptArcCenter) ' Creo un segmento avente origine nel centro dell'arco e direzione opposta a quella del movimento Dim nDistLine As Integer = EgtCreateLinePVL(EgtGetParent(ccompoRawPartOutlineId), ptArcCenter, vtOrigMove.Loc(ccompoRawPartOutlineId), 10000) ' cerco punto di intersezione tra il segmento e l'offset Dim ptDist As Point3d If EgtIntersectionPoint(nDistLine, ccompoRawPartOutlineOffsetId, ptArcCenter, ptDist) Then ' calcolo il vettore di spostamento necessario ad allinearli Dim vtDelta As Vector3d = -(ptDist - ptArcCenter) vtDelta.z = 0 ' se il vettore non è nullo If vtDelta.IsSmall() Then ' il grezzo è in battuta sul riferimento Dim nContactColDisk As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_DISK) EgtSetColor(nContactColDisk, ReferenceContactColGreen) Else vtDelta = vtDelta.Glob(ccompoRawPartOutlineId) ' il vettore da restituire è nullo, quindi lo inizializzo If vtRefMove.IsSmall() Then vtRefMove = vtDelta ' altrimenti lo confronto Else ' per ogni coordinata devo prendere il massimo in direzione opposta allo spostamento originale ' calcolo il versore nella direzione del movimento Dim vtMoveVers As New Vector3d(vtOrigMove) vtMoveVers.Normalize() If (vtDelta * vtMoveVers) < (vtRefMove * vtMoveVers) Then vtRefMove = vtDelta End If End If End If End If ' cancello segmento e offset EgtErase(nDistLine) EgtErase(ccompoRawPartOutlineOffsetId) Else ' il grezzo non è in battuta sul riferimento Dim nContactColDisk As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_DISK) EgtSetColor(nContactColDisk, ReferenceContactColRed) End If End Select ' se non c'è sovrapposizione ElseIf FixtureType(nFixtureId) = FIX_TYPE.REFERENCE Then ' il grezzo non è in battuta sul riferimento Dim nContactColDisk As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_DISK) EgtSetColor(nContactColDisk, ReferenceContactColRed) End If nFixtureId = EgtGetNextFixture(nFixtureId) End While ' se non ci sono ventose sotto il grezzo If Not bIsFixtureUnderRawPart Then ' verifico che il grezzo sia ad altezza tavola If dRawPartMin.z <> 0 Then Dim vtMove As New Vector3d(0, 0, -dRawPartMin.z) EgtMoveRawPart(nRawId, vtMove) End If Else ' se ci sono verifico che l'altezza del grezzo sia quella della ventosa più alta If Math.Abs(dRawPartMin.z - dMaxFixtureHeight) > EPS_SMALL Then Dim vtMove As New Vector3d(0, 0, dMaxFixtureHeight - dRawPartMin.z) EgtMoveRawPart(nRawId, vtMove) End If End If Return True End Function ' Funzione che verifica i movimenti della barra Private Shared Function VerifyBarPosition(nMoveId As Integer, vtMove As Vector3d) As Boolean ' verifico direzione di spostamento consentita Dim sMDir As String = "" EgtGetInfo(nMoveId, MDIR, sMDir) Dim aMDir() As String = sMDir.Split(","c) Dim vX As Integer = 0 Dim vY As Integer = 0 Dim vZ As Integer = 0 Integer.TryParse(aMDir(0), vX) Integer.TryParse(aMDir(1), vY) Integer.TryParse(aMDir(2), vZ) Dim vtMDir As New Vector3d(vX, vY, vZ) vtMDir.Normalize() vtMove = vtMove * vtMDir * vtMDir ' recupero corsa Dim sStroke As String = "" Dim sStrokes() As String Dim PStroke As Double = 0 Dim MStroke As Double = 0 EgtGetInfo(nMoveId, STROKE, sStroke) sStrokes = sStroke.Split(","c) StringToDouble(sStrokes(0), MStroke) StringToDouble(sStrokes(1), PStroke) ' recupero dati barra corrente Dim dCurrBarYPos As Double = 0 Dim dCurrBarMVal As Double = 0 Dim dCurrBarPVal As Double = 0 GetBarExtreme(nMoveId, dCurrBarYPos, dCurrBarMVal, dCurrBarPVal) ' recupero indice barra da spostare Dim sBarName As String = "" EgtGetName(nMoveId, sBarName) Dim nBarId As Integer = 0 sBarName = sBarName.Substring(6, sBarName.Length - 6) Integer.TryParse(sBarName, nBarId) ' recupero dati barra precedente Dim dMinYMove As Double Dim dMaxYMove As Double Dim dPrevBarYPos As Double = 0 Dim dPrevBarMVal As Double = 0 Dim dPrevBarPVal As Double = 0 If nBarId > 1 Then ' recupero eventuale barra precedente Dim nPrevBarId As Integer = EgtGetFirstNameInGroup(EgtGetParent(nMoveId), MOBILE & nBarId - 1) If Not nPrevBarId = GDB_ID.NULL Then GetBarExtreme(nPrevBarId, dPrevBarYPos, dPrevBarMVal, dPrevBarPVal) ' calcolo il massimo tra corsa di spostamento ed ingombro della barra precedente dMinYMove = Math.Max(dPrevBarYPos + dPrevBarPVal + dCurrBarMVal, MStroke) Else dMinYMove = MStroke End If Else dMinYMove = MStroke End If ' recupero eventuale barra successiva Dim dNextBarYPos As Double = 0 Dim dNextBarMVal As Double = 0 Dim dNextBarPVal As Double = 0 Dim nNextBarId As Integer = EgtGetFirstNameInGroup(EgtGetParent(nMoveId), MOBILE & nBarId + 1) If Not nNextBarId = GDB_ID.NULL Then GetBarExtreme(nNextBarId, dNextBarYPos, dNextBarMVal, dNextBarPVal) ' calcolo il minimo tra corsa di spostamento ed ingombro della barra successiva dMaxYMove = Math.Min(dNextBarYPos - dNextBarMVal - dCurrBarPVal, PStroke) Else dMaxYMove = PStroke End If ' sottraggo dagli estremi l'ingombro della barra 'dMinYMove += dCurrBarMVal 'dMaxYMove -= dCurrBarPVal ' verifico che lo spostamento sia entro le corse If dCurrBarYPos + vtMove.y <= dMinYMove Then vtMove.y = dMinYMove - dCurrBarYPos ElseIf dCurrBarYPos + vtMove.y >= dMaxYMove Then vtMove.y = dMaxYMove - dCurrBarYPos End If EgtMove(nMoveId, vtMove) ' scrivo nuova posizione EgtSetInfo(nMoveId, POS, DoubleToString(dCurrBarYPos + vtMove.y, 4)) Return True End Function Private Shared Function GetBarExtreme(nMoveId As Integer, ByRef YPos As Double, ByRef PVal As Double, ByRef MVal As Double) As Boolean ' recupero posizione EgtGetInfo(nMoveId, POS, YPos) ' recupero ingombro negativo Dim dMDist As Double = 0 EgtGetInfo(nMoveId, MDIST, dMDist) ' recupero ingombro positivo Dim dPDist As Double = 0 EgtGetInfo(nMoveId, PDIST, dPDist) MVal = dMDist PVal = dPDist Return True End Function ' Funzione che verifica l'agganciamento dei sottopezzi Friend Shared Function VerifyHookFixture(nMoveId As Integer, ByRef vtMove As Vector3d, ptCurr As Point3d, bTolerance As Boolean) As Boolean ' cerco punto hook sulla ventosa Dim nFixtSolidId As Integer = EgtGetFirstNameInGroup(nMoveId, SOLID) Dim nFixtHookId As Integer = EgtGetFirstNameInGroup(nFixtSolidId, HOOK) ' leggo tipo e classe Dim nFixtHookType As HOOKTYPE = HOOKTYPE.FREE Dim sType As String = "" EgtGetInfo(nFixtHookId, TYPE, sType) If sType.Equals(POINT) Then nFixtHookType = HOOKTYPE.POINT ElseIf sType.Equals(LINE) Then nFixtHookType = HOOKTYPE.LINE Else 'FREE nFixtHookType = HOOKTYPE.FREE ' esco perchè non devo cercare alcun punto Return True End If Dim nFixtHookClass As Integer = 0 EgtGetInfo(nFixtHookId, CLASS_, nFixtHookClass) ' recupero punto di hook Dim ptFixtHook As Point3d EgtStartPoint(nFixtHookId, GDB_ID.ROOT, ptFixtHook) ' calcolo vtMove nel caso normale If Not IsNothing(ptCurr) Then vtMove = ptCurr - m_vtHook - ptFixtHook End If ' cerco id tavola Dim sTableName As String = "" EgtGetTableName(sTableName) Dim nTableId As Integer = EgtGetTableId(sTableName) ' cerco hook su tavola macchina Dim nTableSolidId As Integer = EgtGetFirstNameInGroup(nTableId, SOLID) Dim nCurrHookId As Integer = EgtGetFirstNameInGroup(nTableSolidId, HOOK) ' variabili per tenere da parte l'entità, la distanza e il punto di hook più vicino alla ventosa Dim nNearestHookId As Integer = GDB_ID.NULL Dim dNearestHookDist As Double = 99999999 Dim ptNearestHook As Point3d = Nothing While nCurrHookId <> GDB_ID.NULL 'HookAnalyzer(nCurrHookId, nFixtHookType, nFixtHookClass, ptFixtHook, nNearestHookId, dNearestHookDist) HookAnalyzer(nCurrHookId, nFixtHookType, nFixtHookClass, ptCurr + m_vtHook, nNearestHookId, dNearestHookDist, ptNearestHook, nMoveId) nCurrHookId = EgtGetNextName(nCurrHookId, HOOK) End While ' cerco hook su barra fissa Dim nTableFixedId As Integer = EgtGetFirstNameInGroup(nTableId, FIXED) nCurrHookId = EgtGetFirstNameInGroup(nTableFixedId, HOOK) While nCurrHookId <> GDB_ID.NULL 'HookAnalyzer(nCurrHookId, nFixtHookType, nFixtHookClass, ptFixtHook, nNearestHookId, dNearestHookDist) HookAnalyzer(nCurrHookId, nFixtHookType, nFixtHookClass, ptCurr + m_vtHook, nNearestHookId, dNearestHookDist, ptNearestHook, nMoveId) nCurrHookId = EgtGetNextName(nCurrHookId, HOOK) End While ' cerco hook su barre mobili Dim nMobileInd As Integer = 1 Dim nMobile As Integer = EgtGetFirstNameInGroup(nTableId, MOBILE & nMobileInd) While nMobile <> GDB_ID.NULL nCurrHookId = EgtGetFirstNameInGroup(nMobile, HOOK) While nCurrHookId <> GDB_ID.NULL 'HookAnalyzer(nCurrHookId, nFixtHookType, nFixtHookClass, ptFixtHook, nNearestHookId, dNearestHookDist) HookAnalyzer(nCurrHookId, nFixtHookType, nFixtHookClass, ptCurr + m_vtHook, nNearestHookId, dNearestHookDist, ptNearestHook, nMoveId) nCurrHookId = EgtGetNextName(nCurrHookId, HOOK) End While nMobileInd += 1 nMobile = EgtGetFirstNameInGroup(nTableId, MOBILE & nMobileInd) End While ' se non ho trovato hook compatibili e liberi esco If nNearestHookId = GDB_ID.NULL Then Return False ' verifico se la distanza minima è inferiore al raggio dell'area di aggancio Dim dHookTolerance As Double = EgtUILib.GetPrivateProfileDouble(S_FIXTURES, K_HOOKTOLERANCE, 50, IniFile.m_sCurrMachIniFilePath) If bTolerance AndAlso dNearestHookDist > dHookTolerance Then Return False ' sostituisco spostamento mouse con spostamento ad hook vtMove = ptNearestHook - ptFixtHook m_nUsedHookId = nNearestHookId ' segno hook come utilizzato SetHookUsed(m_nUsedHookId, nMoveId, True) 'EgtSetInfo(m_nUsedHookId, USED, nMoveId) Return True End Function ' funzione di debug Private Shared Sub DebugHookInfo() ' salvo in outlog tutte le info sugli hook per poter debuggare ' cerco id tavola Dim sTableName As String = "" EgtGetTableName(sTableName) Dim nTableId As Integer = EgtGetTableId(sTableName) ' cerco hook su tavola macchina Dim nTableSolidId As Integer = EgtGetFirstNameInGroup(nTableId, SOLID) Dim nCurrHookId As Integer = EgtGetFirstNameInGroup(nTableSolidId, HOOK) EgtOutLog("TABLE") While nCurrHookId <> GDB_ID.NULL Dim sUsed As String = "" EgtGetInfo(nCurrHookId, USED, sUsed) EgtOutLog(nCurrHookId & " -> " & sUsed) nCurrHookId = EgtGetNextName(nCurrHookId, HOOK) End While ' cerco hook su barra fissa EgtOutLog("FIXED") Dim nTableFixedId As Integer = EgtGetFirstNameInGroup(nTableId, FIXED) nCurrHookId = EgtGetFirstNameInGroup(nTableFixedId, HOOK) While nCurrHookId <> GDB_ID.NULL Dim sUsed As String = "" EgtGetInfo(nCurrHookId, USED, sUsed) EgtOutLog(nCurrHookId & " -> " & sUsed) nCurrHookId = EgtGetNextName(nCurrHookId, HOOK) End While ' cerco hook su barre mobili Dim nMobileInd As Integer = 1 Dim nMobile As Integer = EgtGetFirstNameInGroup(nTableId, MOBILE & nMobileInd) While nMobile <> GDB_ID.NULL EgtOutLog("MOBILE" & nMobile) nCurrHookId = EgtGetFirstNameInGroup(nMobile, HOOK) While nCurrHookId <> GDB_ID.NULL Dim sUsed As String = "" EgtGetInfo(nCurrHookId, USED, sUsed) EgtOutLog(nCurrHookId & " -> " & sUsed) nCurrHookId = EgtGetNextName(nCurrHookId, HOOK) End While nMobileInd += 1 nMobile = EgtGetFirstNameInGroup(nTableId, MOBILE & nMobileInd) End While End Sub ' funzioni che leggono e settano le ventose agganciate agli hook Private Shared Function GetHookUsed(nHookId As Integer, nFixtureId As Integer, nFixtureUsed As Integer) As Boolean ' cerco punto hook sulla ventosa Dim nFixtSolidId As Integer = EgtGetFirstNameInGroup(nFixtureId, SOLID) Dim nFixtHookId As Integer = EgtGetFirstNameInGroup(nFixtSolidId, HOOK) ' leggo tipo e classe Dim nFixtHookType As HOOKTYPE = HOOKTYPE.FREE Dim sType As String = "" EgtGetInfo(nFixtHookId, TYPE, sType) If sType.Equals(POINT) Then nFixtHookType = HOOKTYPE.POINT ElseIf sType.Equals(LINE) Then nFixtHookType = HOOKTYPE.LINE Else 'FREE nFixtHookType = HOOKTYPE.FREE ' esco perchè non devo cercare alcun punto Return False End If Select Case nFixtHookType Case HOOKTYPE.POINT Return EgtGetInfo(m_nUsedHookId, USED, nFixtureUsed) Case HOOKTYPE.LINE Dim sInfo As String = String.Empty EgtGetInfo(m_nUsedHookId, USED, sInfo) Dim SplitInfo() As String = sInfo.Split(";"c) For Each Info In SplitInfo Dim nInfo As Integer = GDB_ID.NULL Integer.TryParse(sInfo, nInfo) If nInfo = nFixtureId Then Return True Next Return False Case Else Return False End Select End Function Private Shared Sub SetHookUsed(nHookId As Integer, nFixtureId As Integer, bUsed As Boolean) ' cerco punto hook sulla ventosa Dim nFixtSolidId As Integer = EgtGetFirstNameInGroup(nFixtureId, SOLID) Dim nFixtHookId As Integer = EgtGetFirstNameInGroup(nFixtSolidId, HOOK) ' leggo tipo e classe Dim nFixtHookType As HOOKTYPE = HOOKTYPE.FREE Dim sType As String = "" EgtGetInfo(nFixtHookId, TYPE, sType) If sType.Equals(POINT) Then nFixtHookType = HOOKTYPE.POINT ElseIf sType.Equals(LINE) Then nFixtHookType = HOOKTYPE.LINE Else 'FREE nFixtHookType = HOOKTYPE.FREE ' esco perchè non devo cercare alcun punto Return End If Select Case nFixtHookType Case HOOKTYPE.POINT If bUsed Then EgtSetInfo(m_nUsedHookId, USED, nFixtureId) Else EgtRemoveInfo(m_nUsedHookId, USED) End If Case HOOKTYPE.LINE If bUsed Then Dim sInfo As String = String.Empty EgtGetInfo(m_nUsedHookId, USED, sInfo) Dim SplitInfo() As String = sInfo.Split(";"c) For Each Info In SplitInfo Dim nInfo As Integer = GDB_ID.NULL Integer.TryParse(sInfo, nInfo) If nInfo = nFixtureId Then Return Next sInfo = sInfo & nFixtureId & ";" EgtSetInfo(m_nUsedHookId, USED, sInfo) Else Dim sInfo As String = String.Empty EgtGetInfo(m_nUsedHookId, USED, sInfo) Dim SplitInfo() As String = sInfo.Split(";"c) sInfo = "" For Each Info In SplitInfo Dim nInfo As Integer = GDB_ID.NULL Integer.TryParse(sInfo, nInfo) If nInfo <> nFixtureId Then sInfo = sInfo & Info & ";" End If Next EgtSetInfo(m_nUsedHookId, USED, sInfo) End If End Select End Sub ' Funzione che analizza gli hook Private Shared Sub HookAnalyzer(nCurrHookId As Integer, nFixtHookType As Integer, nFixtHookClass As Integer, ptFixtHook As Point3d, ByRef nNearestHookId As Integer, ByRef dNearestHookDist As Double, ByRef ptNearestHook As Point3d, nMoveId As Integer) ' verifico se del tipo giusto Dim nTableHookType As GDB_TY = EgtGetType(nCurrHookId) If (nTableHookType = GDB_TY.GEO_POINT And nFixtHookType = HOOKTYPE.POINT) OrElse (nTableHookType = GDB_TY.CRV_LINE And nFixtHookType = HOOKTYPE.LINE) Then ' verifico se della stessa classe Dim nTableHookClass As Integer = 0 EgtGetInfo(nCurrHookId, CLASS_, nTableHookClass) If nTableHookClass = nFixtHookClass Then Dim dDist As Double = 0 ' punto a distanza minima sull'hook Dim ptCurrHook As Point3d If nTableHookType = GDB_TY.GEO_POINT Then ' verifico se utilizzato Dim nTableHookUsed As Integer = GDB_ID.NULL If EgtGetInfo(nCurrHookId, USED, nTableHookUsed) AndAlso nTableHookUsed <> nMoveId Then Return If nTableHookUsed = nMoveId Then SetHookUsed(nCurrHookId, nMoveId, False) 'EgtRemoveInfo(nCurrHookId, USED) m_nPrevUsedHookId = nCurrHookId End If ' calcolo distanza punto hook tavola dal punto hook della ventosa EgtStartPoint(nCurrHookId, GDB_ID.ROOT, ptCurrHook) dDist = Point3d.Dist(ptCurrHook, ptFixtHook) 'If nTableHookUsed <> nMoveId Then ' ' calcolo distanza punto hook tavola dal punto hook della ventosa ' EgtStartPoint(nCurrHookId, GDB_ID.ROOT, ptCurrHook) ' dDist = Point3d.Dist(ptCurrHook, ptFixtHook) 'Else ' EgtRemoveInfo(nCurrHookId, USED) ' m_nPrevUsedHookId = nCurrHookId ' Return 'End If 'If Not EgtGetInfo(nCurrHookId, USED, nTableHookUsed) Or nTableHookUsed = nMoveId Then ' ' calcolo distanza punto hook tavola dal punto hook della ventosa ' EgtStartPoint(nCurrHookId, GDB_ID.ROOT, ptCurrHook) ' dDist = Point3d.Dist(ptCurrHook, ptFixtHook) 'Else ' Return 'End If ElseIf nTableHookType = GDB_TY.CRV_LINE Then ' calcolo distanza linea hook tavola dal punto hook della ventosa Dim nRefId As Integer = 0 Dim dU As Double = 0 EgtPointCurveDist(ptFixtHook, nCurrHookId, nRefId, dDist, dU) EgtAtParamPoint(nCurrHookId, dU, GDB_ID.ROOT, ptCurrHook) Else Return End If ' se minore della distanza minima, sostituisco il valore If dDist < dNearestHookDist Then nNearestHookId = nCurrHookId dNearestHookDist = dDist ptNearestHook = ptCurrHook End If Else Return End If Else Return End If End Sub ' Funzione che fissa il vettore di hook Friend Shared Sub VtHookFinder(nFixtureId As Integer, ptCurr As Point3d) ' cerco punto hook sulla ventosa Dim nFixtSolidId As Integer = EgtGetFirstNameInGroup(nFixtureId, SOLID) Dim nFixtHookId As Integer = EgtGetFirstNameInGroup(nFixtSolidId, HOOK) ' recupero punto di hook Dim ptFixtHook As Point3d EgtStartPoint(nFixtHookId, GDB_ID.ROOT, ptFixtHook) m_vtHook = ptCurr - ptFixtHook End Sub ' Funzione che restituisce il tipo di sottopezzo passatogli Friend Shared Function FixtureType(nFixtureId As Integer) As FIX_TYPE Dim sFixtureType As String = String.Empty EgtGetInfo(nFixtureId, EgtUILib.FIX_TYPE, sFixtureType) Select Case sFixtureType Case FIX_VAC Return FIX_TYPE.VACUUM Case FIX_REF Return FIX_TYPE.REFERENCE Case FIX_VIS Return FIX_TYPE.VISE End Select Return FIX_TYPE.NULL End Function Public Enum FIX_TYPE As Integer NULL = 0 VACUUM = 1 REFERENCE = 2 VISE = 3 End Enum ' Funzione che seleziona i sottopezzi del grezzo passatogli Friend Shared Sub SelectRawPartFixture(nRawPartId As Integer) Dim bboxRawPart As New BBox3d Dim bboxFixture As New BBox3d ' ricavo solido del grezzo Dim nRawPartSolid As Integer = EgtGetFirstNameInGroup(nRawPartId, RAWSOLID) ' ne ricavo il bbox EgtGetBBoxGlob(nRawPartSolid, GDB_BB.ONLY_VISIBLE, bboxRawPart) Dim nFixtureId As Integer = EgtGetFirstFixture() While nFixtureId <> GDB_ID.NULL ' ricavo il bbox del sottopezzo EgtGetBBoxGlob(nFixtureId, GDB_BB.ONLY_VISIBLE, bboxFixture) ' verifico se si sovrappongono If bboxRawPart.OverlapsXY(bboxFixture) Then ' seleziono il sottopezzo EgtSelectObj(nFixtureId) End If nFixtureId = EgtGetNextFixture(nFixtureId) End While End Sub ' Funzione che deseleziona i sottopezzi del grezzo passatogli Friend Shared Sub DeselectRawPartFixture(nRawPartId As Integer) Dim bboxRawPart As New BBox3d Dim bboxFixture As New BBox3d ' ricavo solido del grezzo Dim nRawPartSolid As Integer = EgtGetFirstNameInGroup(nRawPartId, RAWSOLID) ' ne ricavo il bbox EgtGetBBoxGlob(nRawPartSolid, GDB_BB.ONLY_VISIBLE, bboxRawPart) Dim nFixtureId As Integer = EgtGetFirstFixture() While nFixtureId <> GDB_ID.NULL ' ricavo il bbox del sottopezzo EgtGetBBoxGlob(nFixtureId, GDB_BB.ONLY_VISIBLE, bboxFixture) ' verifico se si sovrappongono If bboxRawPart.OverlapsXY(bboxFixture) Then ' deseleziono il pezzo EgtDeselectObj(nFixtureId) End If nFixtureId = EgtGetNextFixture(nFixtureId) End While End Sub ' Costante che identifica l'informazione contenente il Frame3d originale del pezzo Private Const ORIG_FRAME As String = "ORIGFRAME" ' Funzione che visualizza i pezzi disponibili e li sposta sotto il grezzo Friend Shared Sub ShowParts() ' prendo riferimento tavola ' ciclo sui pezzi Dim nPartId As Integer = EgtGetFirstPart() While nPartId <> GDB_ID.NULL ' mi faccio dare il riferimento del pezzo prima si spostarlo Dim frOrigPart As New Frame3d EgtGetGroupGlobFrame(nPartId, frOrigPart) ' salvo il riferimento originale EgtSetInfo(nPartId, ORIG_FRAME, frOrigPart) ' ' Attivo la visualizzazione del pezzo mettendolo in modalità standard EgtSetStatus(nPartId, GDB_ST.ON_) ' prendo il pezzo successivo nPartId = EgtGetNextPart(nPartId) End While EgtDraw() End Sub ' Funzione che rimette a posto i pezzi Friend Shared Sub HideParts() ' ciclo sui pezzi Dim nPartId As Integer = EgtGetFirstPart() While nPartId <> GDB_ID.NULL ' recupero il riferimento originale Dim frOrigPart As New Frame3d EgtGetInfo(nPartId, ORIG_FRAME, frOrigPart) ' lo ripristino EgtChangeGroupFrame(nPartId, frOrigPart) ' Attivo la visualizzazione del pezzo mettendolo in modalità standard EgtSetStatus(nPartId, GDB_ST.OFF) ' prendo il pezzo successivo nPartId = EgtGetNextPart(nPartId) End While End Sub End Class