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 Public ReadOnly Property OkMsg As String Get Return "" 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 ' se movimento di traslazione 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() ' se è un grezzo If EgtVerifyRawPartCurrPhase(nFirstSelectedId) Then ' imposto il riferimento della tavola Dim ptTableRef As Point3d EgtGetTableRef(1, ptTableRef) ' calcolo il punto del grezzo da posizionar nelle coordinate di input Dim ptRawRefPoint As Point3d = GetRawPartRefPoint(nFirstSelectedId, m_RawRefPosition) ' 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 ' se è una ventosa 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) ' se è un grezzo If EgtVerifyRawPartCurrPhase(nFirstSelectedId) Then Dim ptRawRefPoint As Point3d = GetRawPartRefPoint(nFirstSelectedId, m_RawRefPosition) ' verifico se lo spostamento effettuato differisce da quello richiesto Dim vtRemainingMove As Vector3d = InputPoint - ptRawRefPoint ' se differisce If Not vtRemainingMove.IsSmall() Then ' eseguo lo spostamento rimanente sull'asse x MoveRawPartPartAndFixture(GDB_ID.SEL, New Vector3d(vtRemainingMove.x, 0, 0)) ' eseguo lo spostamento rimanente sull'asse y MoveRawPartPartAndFixture(GDB_ID.SEL, New Vector3d(0, vtRemainingMove.y, 0)) End If End If ' se rotazione 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 Private 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.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 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, 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 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 '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, 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) 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 ' 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.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) ' 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 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 coincidono, esco If vtDelta.IsSmall() Then ' il grezzo è in battuta sul riferimento Dim nContactColDisk As Integer = EgtGetFirstNameInGroup(EgtGetFirstNameInGroup(nFixtureId, SOLID), REF_CONTACTCOLDISK) 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_CONTACTCOLDISK) 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_CONTACTCOLDISK) EgtSetColor(nContactColDisk, ReferenceContactColRed) End If 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) ' 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_CONTACTCOLDISK) 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_CONTACTCOLDISK) 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_CONTACTCOLDISK) 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 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