Imports EgtUILib Namespace EgtCAM5 Public Class DispositionParameterExpanderViewModel Inherits ViewModelBase Public Enum ObjectType As Integer RAWPART = 1 PART = 2 FIXTURE = 3 End Enum Private m_ActiveObject As ObjectType Public Property ActiveObject As ObjectType Get Return m_ActiveObject End Get Set(value As ObjectType) If value <> m_ActiveObject Then Select Case value Case ObjectType.RAWPART RawPartIsExpanded = True Case ObjectType.PART PartIsExpanded = True Case ObjectType.FIXTURE FixtureIsExpanded = True End Select m_ActiveObject = value End If m_ActiveObject = value End Set End Property Friend m_Id As Integer Public ReadOnly Property Id As Integer Get Return m_Id End Get End Property Private m_Name As String Public Property Name As String Get Return m_Name End Get Set(value As String) m_Name = value End Set End Property Private m_RawPartIsExpanded As Boolean Public Property RawPartIsExpanded As Boolean Get Return m_RawPartIsExpanded End Get Set(value As Boolean) If value <> m_RawPartIsExpanded Then If value Then ' Chiudo Part e Fixture PartIsExpanded = False FixtureIsExpanded = False ' verifico se è attiva l'opzione muovi con ventose If m_MoveWithFixture Then ' Abilito la selezione dei RawPart con ventose Application.Msn.NotifyColleagues(Application.SETSCENESELTYPE, SceneSelTypeOpt.RAWPARTWITHFIXTURE) Else ' Abilito la selezione dei RawPart Application.Msn.NotifyColleagues(Application.SETSCENESELTYPE, SceneSelTypeOpt.RAWPART) End If If m_MoveIsChecked Then m_RawRefGroupVisibility = Visibility.Visible OnPropertyChanged("RawRefGroupVisibility") End If Else ' Nascondo i bottoni per impostare la posizione di riferimento del grezzo m_RawRefGroupVisibility = Visibility.Collapsed OnPropertyChanged("RawRefGroupVisibility") ' smarco la prima entità selezionata EgtResetMark(EgtGetFirstSelectedObj) EgtDeselectAll() EgtDraw() End If m_RawPartIsExpanded = value ActiveObject = ObjectType.RAWPART OnPropertyChanged("RawPartIsExpanded") End If End Set End Property Private m_PartIsExpanded As Boolean Public Property PartIsExpanded As Boolean Get Return m_PartIsExpanded End Get Set(value As Boolean) If value <> m_PartIsExpanded Then If value Then ' Chiudo RawPart e Fixture RawPartIsExpanded = False FixtureIsExpanded = False Else ' smarco la prima entità selezionata EgtResetMark(EgtGetFirstSelectedObj) EgtDeselectAll() EgtDraw() End If m_PartIsExpanded = value ActiveObject = ObjectType.PART OnPropertyChanged("PartIsExpanded") End If End Set End Property Private m_FixtureIsExpanded As Boolean Public Property FixtureIsExpanded As Boolean Get Return m_FixtureIsExpanded End Get Set(value As Boolean) If value <> m_FixtureIsExpanded Then If value Then ' Chiudo RawPart e Part RawPartIsExpanded = False PartIsExpanded = False ' Abilito la selezione delle Fixture Application.Msn.NotifyColleagues(Application.SETSCENESELTYPE, SceneSelTypeOpt.FIXTURE) Else ' smarco la prima entità selezionata EgtResetMark(EgtGetFirstSelectedObj) ' deseleziono tutto ed aggiorno la visualizzazione EgtDeselectAll() EgtDraw() End If m_FixtureIsExpanded = value ActiveObject = ObjectType.FIXTURE OnPropertyChanged("FixtureIsExpanded") End If End Set End Property Private m_MoveIsChecked As Boolean Public Property MoveIsChecked As Boolean Get Return m_MoveIsChecked End Get Set(value As Boolean) If value <> m_MoveIsChecked Then Application.Msn.NotifyColleagues(Application.SETMOVEINDISPOSITION, value) InputValue = String.Empty OnPropertyChanged("InputValue") If value Then If m_RawPartIsExpanded Then m_RawRefGroupVisibility = Visibility.Visible OnPropertyChanged("RawRefGroupVisibility") Else m_RawRefGroupVisibility = Visibility.Collapsed OnPropertyChanged("RawRefGroupVisibility") End If m_InputMsg = "Move to:" Else m_RawRefGroupVisibility = Visibility.Collapsed OnPropertyChanged("RawRefGroupVisibility") m_InputMsg = "Rotate of:" End If OnPropertyChanged("InputMsg") m_MoveIsChecked = value End If End Set End Property Private m_MoveWithFixture As Boolean = False Public Property MoveWithFixture As Boolean Get Return m_MoveWithFixture End Get Set(value As Boolean) If value <> m_MoveWithFixture Then If value Then ' Abilito la selezione di RawPart con autoselezione delle sue ventose Application.Msn.NotifyColleagues(Application.SETSCENESELTYPE, SceneSelTypeOpt.RAWPARTWITHFIXTURE) ' Seleziono le ventose associate ad uno dei grezzi selezionati ' ciclo sui grezzi selezionati Dim nSelRawPartId As Integer = EgtGetFirstSelectedObj() While nSelRawPartId <> GDB_ID.NULL ' seleziono i sottopezzi del grezzo SelectRawPartFixture(nSelRawPartId) nSelRawPartId = EgtGetNextSelectedObj() End While Else ' Abilito la selezione di RawPart Application.Msn.NotifyColleagues(Application.SETSCENESELTYPE, SceneSelTypeOpt.RAWPART) ' ciclo sui grezzi selezionati Dim nSelRawPartId As Integer = EgtGetFirstSelectedObj() While nSelRawPartId <> GDB_ID.NULL ' deseleziono i sottopezzi del grezzo DeselectRawPartFixture(nSelRawPartId) nSelRawPartId = EgtGetNextSelectedObj() End While End If EgtDraw() m_MoveWithFixture = value OnPropertyChanged("MoveWithFixture") End If End Set End Property Private m_InputValue As String Public Property InputValue As String Get Return m_InputValue End Get Set(value As String) If Not String.IsNullOrEmpty(m_InputErrorMsg) Then m_InputErrorMsg = String.Empty OnPropertyChanged("InputErrorMsg") End If m_InputValue = value End Set End Property Private m_BLIsChecked As Boolean = True Public ReadOnly Property BLIsChecked As Boolean Get Return m_BLIsChecked End Get End Property Private m_RawRefPosition As MCH_CR = MCH_CR.BL Private m_RawRefGroupVisibility As Visibility Public ReadOnly Property RawRefGroupVisibility As Visibility Get Return m_RawRefGroupVisibility End Get End Property #Region "Messages" Private m_InputMsg As String Public ReadOnly Property InputMsg As String Get Return m_InputMsg End Get End Property Private m_InputErrorMsg As String Public ReadOnly Property InputErrorMsg As String Get Return m_InputErrorMsg End Get End Property #End Region ' Messages ' Definizione comandi Private m_cmdDone As ICommand Private m_cmdCheckedRawRef As ICommand #Region "CONSTRUCTOR" Sub New(ByRef OpenDispositionFunction As Action(Of Boolean)) OpenDispositionFunction = AddressOf OpenDispositionParameters MoveIsChecked = True m_BLIsChecked = True OnPropertyChanged("BLIsChecked") m_RawRefPosition = MCH_CR.BL End Sub #End Region #Region "METHODS" Public Sub OpenDispositionParameters(bFirst As Boolean) If bFirst Then ActiveObject = ObjectType.RAWPART Else ActiveObject = ObjectType.FIXTURE End If Select Case m_ActiveObject Case ObjectType.RAWPART ' Abilito la selezione delle Fixture Application.Msn.NotifyColleagues(Application.SETSCENESELTYPE, SceneSelTypeOpt.RAWPART) Case ObjectType.FIXTURE ' Abilito la selezione delle Fixture Application.Msn.NotifyColleagues(Application.SETSCENESELTYPE, SceneSelTypeOpt.FIXTURE) End Select m_MoveWithFixture = False OnPropertyChanged("MoveWithFixture") End Sub #End Region ' METHODS #Region "COMMANDS" #Region "DoneCommand" ''' ''' Returns a command that do Done. ''' Public ReadOnly Property DoneCommand As ICommand Get If m_cmdDone Is Nothing Then m_cmdDone = New RelayCommand(AddressOf Done) End If Return m_cmdDone End Get End Property ''' ''' Execute the Point. This method is invoked by the DoneCommand. ''' Public Sub Done(ByVal param As Object) ' Verifico la validità del punto in Input If Not String.IsNullOrEmpty(m_InputValue) Then If m_MoveIsChecked Then Dim InputPoint As New Point3d(0, 0, 0) Dim Values() As String = m_InputValue.Split(","c) If Values.Count = 2 Then StringToLen(Values(0), InputPoint.x) StringToLen(Values(1), InputPoint.y) Else m_InputErrorMsg = "Il valore non è una cordinata XY" OnPropertyChanged("InputErrorMsg") Return End If ' Vettore di movimento Dim vtMove As Vector3d ' lo imposto a seconda del tipo del primo elemento selezionato Dim nFirstSelectedId As Integer = EgtGetFirstSelectedObj() If EgtVerifyRawPartCurrPhase(nFirstSelectedId) Then Dim bboxRawPart As New BBox3d ' recupero il solido del grezzo dal primo elemento selezionato Dim nRawSolidId As Integer = EgtGetFirstNameInGroup(nFirstSelectedId, RAWSOLID) ' ne calcolo il BBox EgtGetBBoxGlob(nRawSolidId, GDB_BB.STANDARD, 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 m_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 ' creo un punto con le coordinate di input espresse rispetto alla tavola Dim TableRefInputPoint As New Point3d(InputPoint) TableRefInputPoint.LocToLoc(EgtGetGridFrame(), New Frame3d(ptTableRef)) ' calcolo il vettore di spostamento del grezzo vtMove = TableRefInputPoint - ptRawRefPoint ElseIf EgtVerifyFixture(nFirstSelectedId) Then Dim SelObjFrame3d As New Frame3d(Frame3d.GLOB) EgtGetGroupGlobFrame(nFirstSelectedId, SelObjFrame3d) SelObjFrame3d.ToLoc(EgtGetGridFrame()) Dim FixturePoint As New Point3d(SelObjFrame3d.Orig) ' Ricavo il vettore di movimento (tengo solo XY) vtMove = InputPoint - FixturePoint vtMove.z = 0 End If ' Muovo tutti gli oggetti selezionati MoveRawPartPartAndFixture(GDB_ID.SEL, vtMove) '' flag che indica se è il primo oggetto selezionato 'Dim bFirstRawId As Boolean = True 'Dim bFirstFixtId As Boolean = True '' Vettore di movimento 'Dim vtRawPartMove As Vector3d 'Dim vtFixtureMove As Vector3d 'Dim nSelId As Integer = EgtGetFirstSelectedObj() 'While nSelId <> GDB_ID.NULL ' Select Case m_ActiveObject ' Case ObjectType.RAWPART ' If bFirstRawId Then ' Dim bboxRawPart As New BBox3d ' EgtGetBBox(nSelId, GDB_BB.STANDARD, bboxRawPart) ' Dim ptRawRefPoint As Point3d ' Select Case m_RawRefPosition ' Case MCH_CR.TL ' ptRawRefPoint.x = bboxRawPart.Min.x ' ptRawRefPoint.y = bboxRawPart.Max.y ' Case MCH_CR.TR ' ptRawRefPoint.x = bboxRawPart.Max.x ' ptRawRefPoint.y = bboxRawPart.Max.y ' Case MCH_CR.BL ' ptRawRefPoint.x = bboxRawPart.Min.x ' ptRawRefPoint.y = bboxRawPart.Min.y ' Case MCH_CR.BR ' ptRawRefPoint.x = bboxRawPart.Max.x ' ptRawRefPoint.y = bboxRawPart.Min.y ' End Select ' ptRawRefPoint.z = bboxRawPart.Min.z ' Dim TableRefInputPoint As New Point3d(InputPoint) ' Dim ptTableRef As Point3d ' EgtGetTableRef(1, ptTableRef) ' TableRefInputPoint.LocToLoc(EgtGetGridFrame(), New Frame3d(ptTableRef)) ' vtRawPartMove = TableRefInputPoint - ptRawRefPoint ' bFirstRawId = False ' End If ' Dim bboxCurrRawPart As New BBox3d ' EgtGetBBox(nSelId, GDB_BB.STANDARD, bboxCurrRawPart) ' Dim ptCurrRawRefPoint As Point3d ' Select Case m_RawRefPosition ' Case MCH_CR.TL ' ptCurrRawRefPoint.x = bboxCurrRawPart.Min.x ' ptCurrRawRefPoint.y = bboxCurrRawPart.Max.y ' Case MCH_CR.TR ' ptCurrRawRefPoint.x = bboxCurrRawPart.Max.x ' ptCurrRawRefPoint.y = bboxCurrRawPart.Max.y ' Case MCH_CR.BL ' ptCurrRawRefPoint.x = bboxCurrRawPart.Min.x ' ptCurrRawRefPoint.y = bboxCurrRawPart.Min.y ' Case MCH_CR.BR ' ptCurrRawRefPoint.x = bboxCurrRawPart.Max.x ' ptCurrRawRefPoint.y = bboxCurrRawPart.Min.y ' End Select ' ptCurrRawRefPoint.z = bboxCurrRawPart.Min.z ' Dim bErrorMoving As Boolean = False ' If Not EgtMoveToCornerRawPart(nSelId, ptCurrRawRefPoint + vtRawPartMove, m_RawRefPosition) Then ' bErrorMoving = True ' ElseIf Not DispositionParameterExpanderViewModel.VerifyRawPartFixturePos(nSelId) Then ' EgtMoveToCornerRawPart(nSelId, ptCurrRawRefPoint, m_RawRefPosition) ' bErrorMoving = True ' End If ' If bErrorMoving Then ' m_InputErrorMsg = "Impossibile muovere il grezzo fuori dalla tavola" ' OnPropertyChanged("InputErrorMsg") ' End If ' Case ObjectType.PART ' 'EgtMove... ' Case ObjectType.FIXTURE ' If bFirstFixtId Then ' Dim SelObjFrame3d As New Frame3d(Frame3d.GLOB) ' EgtGetGroupGlobFrame(nSelId, SelObjFrame3d) ' SelObjFrame3d.ToLoc(EgtGetGridFrame()) ' Dim FixturePoint As New Point3d(SelObjFrame3d.Orig) ' ' Ricavo il vettore di movimento (tengo solo XY) ' vtFixtureMove = InputPoint - FixturePoint ' vtFixtureMove.z = 0 ' bFirstFixtId = False ' End If ' Dim nErrorMoving As Integer = 0 ' If Not EgtMoveFixture(nSelId, vtFixtureMove) Then ' nSelId = EgtGetPrevSelectedObj() ' nErrorMoving = 1 ' ElseIf Not DispositionParameterExpanderViewModel.VerifyRawPartFixturePos(nSelId) Then ' nErrorMoving = 2 ' End If ' If nErrorMoving <> 0 Then ' If nErrorMoving = 1 Then ' m_InputErrorMsg = "Impossibile muovere una ventosa fuori dalla tavola" ' ElseIf nErrorMoving = 2 Then ' m_InputErrorMsg = "Posizione già occupata da un'altra ventosa" ' End If ' OnPropertyChanged("InputErrorMsg") ' While nSelId <> GDB_ID.NULL ' If EgtVerifyFixture(nSelId) Then ' EgtMoveFixture(nSelId, -vtFixtureMove) ' ElseIf EgtVerifyRawPartCurrPhase(nSelId) Then ' EgtMoveRawPart(nSelId, -vtFixtureMove) ' End If ' nSelId = EgtGetPrevSelectedObj() ' End While ' End If ' End Select 'nSelId = EgtGetNextSelectedObj() 'End While Else Dim InputAngle As Double = 0 If Not StringToDouble(m_InputValue, InputAngle) Then m_InputErrorMsg = "Il valore non è un angolo valido" OnPropertyChanged("InputErrorMsg") Return End If Dim nSelId As Integer = EgtGetFirstSelectedObj() While nSelId <> GDB_ID.NULL Select Case m_ActiveObject Case ObjectType.RAWPART If Not EgtRotateRawPart(nSelId, Vector3d.Z_AX, InputAngle) Then m_InputErrorMsg = "Impossibile ruotare il grezzo." OnPropertyChanged("InputErrorMsg") End If Case ObjectType.PART 'EgtMove... Case ObjectType.FIXTURE If Not EgtRotateFixture(nSelId, InputAngle) Then m_InputErrorMsg = "Impossibile ruotare la ventosa" OnPropertyChanged("InputErrorMsg") End If End Select nSelId = EgtGetNextSelectedObj() End While End If EgtDraw() End If End Sub Public Shared Function MoveRawPartPartAndFixture(nMoveId As Integer, vtMove As Vector3d) 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 If EgtVerifyFixture(nMoveId) Then If Not EgtMoveFixture(nMoveId, vtMove) Then bErrorMoving = True End If 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 DispositionParameterExpanderViewModel.VerifyRawPartFixturePos(nSelObjId, vtMove, vtRefMove) Then bErrorVerify = True Exit While End If nSelObjId = EgtGetNextSelectedObj() End While Else If Not DispositionParameterExpanderViewModel.VerifyRawPartFixturePos(nMoveId, vtMove, vtRefMove) Then bErrorVerify = True End If End If End If ' se non c'è errore ma c'è spostamento per correzione riferimento If Not bErrorVerify AndAlso Not vtRefMove.IsSmall Then ' provo a spostare bErrorVerify = Not MoveRawPartPartAndFixture(nMoveId, vtRefMove) 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) 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 Private 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.STANDARD, 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.STANDARD, 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.STANDARD, bboxFixture) Dim bboxRawPart As New BBox3d ' 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.STANDARD, 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.STANDARD, 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.STANDARD, 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) ' 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 EgtGetMinDistPntSidePointCurve(ptArcCenter, ccompoRawPartOutlineOffsetId, Vector3d.Z_AX, 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 non coincidono, esco If Not vtDelta.IsSmall() Then ' altrimenti riporto il vettore di correzione vtRefMove = -vtDelta.Glob(ccompoRawPartOutlineId) End If End If End Select End If nRawPartId = EgtGetNextRawPart(nRawPartId) End While Return True End Function Private 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.STANDARD, 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.STANDARD, 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.STANDARD, 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.STANDARD, 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.STANDARD, bboxRawPartId) 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) ' 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, ccompoRawPartOutlineOffsetId, 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 Not vtDelta.IsSmall() Then ' il vettore da restituire è nullo, quindi lo inizializzo If vtRefMove.IsSmall() Then vtRefMove = vtDelta.Glob(ccompoRawPartOutlineId) ' 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 '' 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 'EgtGetMinDistPntSidePointCurve(ptArcCenter, ccompoRawPartOutlineOffsetId, Vector3d.Z_AX, dDist, ptMin, nSide) ' cancello offset e segmento EgtErase(ccompoRawPartOutlineOffsetId) EgtErase(nDistLine) End Select 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 restituisce il tipo di sottopezzo passatogli Friend Shared Function FixtureType(nFixtureId As Integer) As FIX_TYPE Dim sFitureType As String = String.Empty EgtGetInfo(nFixtureId, EgtUILib.FIX_TYPE, sFitureType) Select Case sFitureType Case FIX_VAC Return FIX_TYPE.VACUUM Case FIX_REF Return FIX_TYPE.REFERENCE End Select Return FIX_TYPE.NULL End Function Friend Enum FIX_TYPE As Integer NULL = 0 VACUUM = 1 REFERENCE = 2 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.STANDARD, bboxRawPart) Dim nFixtureId As Integer = EgtGetFirstFixture() While nFixtureId <> GDB_ID.NULL ' ricavo il bbox del sottopezzo EgtGetBBoxGlob(nFixtureId, GDB_BB.STANDARD, 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.STANDARD, bboxRawPart) Dim nFixtureId As Integer = EgtGetFirstFixture() While nFixtureId <> GDB_ID.NULL ' ricavo il bbox del sottopezzo EgtGetBBoxGlob(nFixtureId, GDB_BB.STANDARD, bboxFixture) ' verifico se si sovrappongono If bboxRawPart.OverlapsXY(bboxFixture) Then ' deseleziono il pezzo EgtDeselectObj(nFixtureId) End If nFixtureId = EgtGetNextFixture(nFixtureId) End While End Sub #End Region ' DoneCommand #Region "CheckedRawRefCommand" ''' ''' Returns a command that do Done. ''' Public ReadOnly Property CheckedRawRefCommand As ICommand Get If m_cmdCheckedRawRef Is Nothing Then m_cmdCheckedRawRef = New RelayCommand(AddressOf CheckedRawRef) End If Return m_cmdCheckedRawRef End Get End Property ''' ''' Execute the Point. This method is invoked by the DoneCommand. ''' Public Sub CheckedRawRef(ByVal param As Object) Dim nRawRef As MCH_CR = DirectCast(param, MCH_CR) m_RawRefPosition = nRawRef End Sub #End Region ' CheckedRawRefCommand #End Region End Class End Namespace