Macro - Cacher les cercle de fraisure (Assistance de perçage)

Bonjour,

J'ai en projet une macro afin de caché les cercles de fraisure sur nos MEP (uniquement sur la 1ère feuille et la 1ère vue)

En sachant qu'il n'y en as pas à chaque fois.

1- Est-ce réalisable à votre avis?

2-Une petite idée sur les fonction pour démarrer? (en particulier comment identifier si le cercle est un cercle d'une fraisure)

 

Ci-dessous un exemple des 2 types de fraisure rencontrés (normal ou dégagement de la tête + chambrage ajouté):

Toute les pistes pouvant m'aider à démarrer, sera le bien venu.

J'ai bien trouvé ceci pour mettre les cercles en rouges mais comment choisir uniquement les cercles de fraisure?

Sub main()
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swDraw = swModel
Set swView = swDraw.ActiveDrawingView
swModel.ClearSelection2 True
vComps = swView.GetVisibleComponents
'Diameter = InputBox("Entrer le diamètre en mm")
For Each vComp In vComps
    Set Comp = vComp
    vEdges = swView.GetVisibleEntities(Comp, swViewEntityType_e.swViewEntityType_Edge)
    For Each vEdge In vEdges
        Set swEdge = vEdge
        Set swCurve = swEdge.GetCurve
        If swCurve.IsCircle Then
            swCurve.GetEndParams Empty, Empty, IsClosed, Empty
            If IsClosed Then
                CurveParam = swCurve.CircleParams
                'If Abs(Diameter - CurveParam(6) * 2 * 1000) < 0.0001 Then
                    Set swEntity = swEdge
                    swEntity.Select4 True, Nothing
                'End If
            End If
        End If
    Next
Next
swModel.SetLineColor 255
swModel.ClearSelection2 True
End Sub

Merci.

1 « J'aime »

Essaye ca:

Option Explicit
Sub main()
Dim swapp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swView As SldWorks.View
Dim vComps As Variant
Dim vComp As Variant
Dim Comp As SldWorks.Component2
Dim vEdges As Variant
Dim vEdge As Variant
Dim swEdge As SldWorks.edge
Dim swCurve As SldWorks.Curve
Dim IsClosed As Boolean
Dim pos As String
Dim CurveParam As Variant
Dim Cercle As Class1
Dim monCercle As Class1
Dim Cercles As Collection
Set swapp = Application.SldWorks
Set swModel = swapp.ActiveDoc
Set swDraw = swModel
Set swView = swDraw.ActiveDrawingView
If swView Is Nothing Then
    MsgBox "Selectionner une vue"
    Exit Sub
End If
Set Cercles = New Collection
vComps = swView.GetVisibleComponents
For Each vComp In vComps
    Set Comp = vComp
    vEdges = swView.GetVisibleEntities(Comp, swViewEntityType_e.swViewEntityType_Edge)
    For Each vEdge In vEdges
        Set swEdge = vEdge
        Set swCurve = swEdge.GetCurve
        If swCurve.IsCircle Then
            swCurve.GetEndParams Empty, Empty, IsClosed, Empty
            If IsClosed Then
                CurveParam = swCurve.CircleParams
                pos = ""
                If Round(CurveParam(3), 3) = 0 Then pos = pos & Round(CurveParam(0), 3) & "-"
                If Round(CurveParam(4), 3) = 0 Then pos = pos & Round(CurveParam(1), 3) & "-"
                If Round(CurveParam(5), 3) = 0 Then pos = pos & Round(CurveParam(2), 3) & "-"
                Debug.Print pos
                Set Cercle = New Class1
                Cercle.pos = pos
                Cercle.dia = Round(CurveParam(6), 3)
                Set Cercle.edge = swEdge
                Cercles.Add Cercle
            End If
        End If
    Next
Next
swModel.ClearSelection2 True
For Each monCercle In Cercles
    For Each Cercle In Cercles
        If Cercle.pos = monCercle.pos And Cercle.dia < monCercle.dia Then
          monCercle.edge.Select4 True, Nothing
        End If
    Next
Next
swDraw.HideEdge
swModel.ForceRebuild3 False
'swModel.SetLineColor 255'
swModel.ClearSelection2 True
End Sub

Insert > Class Module > nommer: Class1

'Class1:'
Public edge As SldWorks.Entity
Public pos As String
Public dia As Single

 

3 « J'aime »

Une fois de plus parfaitement fonctionnel. Merci une nouvelle fois JeromeP .

Par contre pas sûr de tout comprendre comment fais tu pour voir que c'est un fraisage?

En gros je ne comprends pas tout dans cette partie:

If swCurve.IsCircle Then
            swCurve.GetEndParams Empty, Empty, IsClosed, Empty
            If IsClosed Then
                CurveParam = swCurve.CircleParams
                pos = ""
                If Round(CurveParam(3), 3) = 0 Then pos = pos & Round(CurveParam(0), 3) & "-"
                If Round(CurveParam(4), 3) = 0 Then pos = pos & Round(CurveParam(1), 3) & "-"
                If Round(CurveParam(5), 3) = 0 Then pos = pos & Round(CurveParam(2), 3) & "-"
                Debug.Print pos
                Set Cercle = New Class1
                Cercle.pos = pos
                Cercle.dia = Round(CurveParam(6), 3)
                Set Cercle.edge = swEdge
                Cercles.Add Cercle

 

1 « J'aime »

Dans cette partie j'enregistre la position (pos) et le diamètre (CurveParam(6)) de chaque cercle + le cercle lui même (swEdge).

Étant donné que la position est en xyz, j'élimine la composante de hauteur en me servant de la direction de l'axe du cercle (CurveParam(3), CurveParam(4), CurveParam(5))

Ce qui me permet ensuite de trouver les cercles de même position, trouver le cercle le plus grand, et le cacher.

 

2 « J'aime »

J'avais bien compris pour le cercle le plus grand, par contre je en comprenais pas comment tu identifiais 2 cercle à la même fonction-> par la position.

Pas bête du tout!

En tout cas merci, il me reste plus cas ajouter ce code au mien pour perfectionner ma macro personnel de nettoyage de plan automatique.

1 « J'aime »

Après quelques tests sur la macro, je viens de m'apercevoir que sur ce type de pièce, il me cache le cercle 1 au lieu de caché uniqement le 2.

Pour l'instant que contourne le problème en ajoutant:

If Cercle.pos = monCercle.pos And Cercle.dia < monCercle.dia And monCercle.dia * 1000 < 38 Then

Car 37mm est le Ø de la vis fraisé M20 qui est la plus grosse utilisé. Y aurait-il une autre solution pour éviter ce soucis ne pas prendre en compte le cercle si il fait parti du contour exterieure ou par rapport au nom... (En sachant que les pièces ne sont pas souvent circulaire.)

1 « J'aime »

Tu peux comparer le diamètre avec les dimensions de la bounding box obtenus avec:

Function GetPreciseBoundingBox(part As SldWorks.PartDoc) As Variant
    Dim dBox(5) As Double
    Dim vBodies As Variant
    vBodies = part.GetBodies2(swBodyType_e.swSolidBody, True)
    Dim minX As Double
    Dim minY As Double
    Dim minZ As Double
    Dim maxX As Double
    Dim maxY As Double
    Dim maxZ As Double
    If Not IsEmpty(vBodies) Then
        Dim i As Integer
        For i = 0 To UBound(vBodies)
            Dim swBody As SldWorks.Body2
            Set swBody = vBodies(i)
            Dim x As Double
            Dim y As Double
            Dim z As Double
            swBody.GetExtremePoint 1, 0, 0, x, y, z
            If i = 0 Or x > maxX Then maxX = x

            swBody.GetExtremePoint -1, 0, 0, x, y, z
            If i = 0 Or x < minX Then minX = x

            swBody.GetExtremePoint 0, 1, 0, x, y, z
            If i = 0 Or y > maxY Then maxY = y

            swBody.GetExtremePoint 0, -1, 0, x, y, z
            If i = 0 Or y < minY Then minY = y

            swBody.GetExtremePoint 0, 0, 1, x, y, z
            If i = 0 Or z > maxZ Then maxZ = z
            
            swBody.GetExtremePoint 0, 0, -1, x, y, z
            If i = 0 Or z < minZ Then minZ = z
        Next
    End If
    dBox(0) = minX: dBox(1) = minY: dBox(2) = minZ
    dBox(3) = maxX: dBox(4) = maxY: dBox(5) = maxZ
    GetPreciseBoundingBox = dBox
End Function

 

1 « J'aime »

Pour appeler ma fonction GetPreciseBoundingBox dans la macro précédente, il faut bien partir de la pièce et pas de la mise en plan?

 

1 « J'aime »

oui il faut appliquer la fonction sur la pièce

1 « J'aime »

Bonjour,

Le code fonction parfaitement depuis ma macro, par contre je n'arrive pas à récupérer les valeurs dans ma macro ou j'appelle la fonction.

J'imagine que les donnée sont enregistré dans une array mais comment en rappeler les valeur depuis ma macro?

Option Explicit
Sub main()
Dim swapp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swView As SldWorks.View
Dim vComps As Variant
Dim vComp As Variant
Dim Comp As SldWorks.Component2
Dim vEdges As Variant
Dim vEdge As Variant
Dim swEdge As SldWorks.edge
Dim swCurve As SldWorks.Curve
Dim IsClosed As Boolean
Dim pos As String
Dim CurveParam As Variant
Dim Cercle As Class1
Dim monCercle As Class1
Dim Cercles As Collection
Set swapp = Application.SldWorks
Set swModel = swapp.ActiveDoc
Set swDraw = swModel
Set swView = swDraw.ActiveDrawingView
If swView Is Nothing Then
    MsgBox "Selectionner une vue"
    Exit Sub
End If

'Ajout SD pour récuperer les valeures de la Bounding Box
Dim swPartModel As SldWorks.ModelDoc2
Set swPartModel = swView.ReferencedDocument
GetPreciseBoundingBox swPartModel
' Fin de l'ajout


Set Cercles = New Collection
vComps = swView.GetVisibleComponents
For Each vComp In vComps
    Set Comp = vComp
    vEdges = swView.GetVisibleEntities(Comp, swViewEntityType_e.swViewEntityType_Edge)
    For Each vEdge In vEdges
        Set swEdge = vEdge
        Set swCurve = swEdge.GetCurve
        If swCurve.IsCircle Then
            swCurve.GetEndParams Empty, Empty, IsClosed, Empty
            If IsClosed Then
                CurveParam = swCurve.CircleParams
                pos = ""
                If Round(CurveParam(3), 3) = 0 Then pos = pos & Round(CurveParam(0), 3) & "-"
                If Round(CurveParam(4), 3) = 0 Then pos = pos & Round(CurveParam(1), 3) & "-"
                If Round(CurveParam(5), 3) = 0 Then pos = pos & Round(CurveParam(2), 3) & "-"
                Debug.Print pos
                Set Cercle = New Class1
                Cercle.pos = pos
                Cercle.dia = Round(CurveParam(6), 3)
                Set Cercle.edge = swEdge
                Cercles.Add Cercle
            End If
        End If
    Next
Next
swModel.ClearSelection2 True
For Each monCercle In Cercles
    For Each Cercle In Cercles
    
        Debug.Print Cercle.dia * 1000
        If Cercle.pos = monCercle.pos And Cercle.dia < monCercle.dia And monCercle.dia * 1000 < 38 Then
          monCercle.edge.Select4 True, Nothing
        End If
    Next
Next
'Modif SD - on ne cache plus temporairement
'swDraw.HideEdge
swModel.ForceRebuild3 False
'swModel.SetLineColor 255 '
swModel.ClearSelection2 True
End Sub

Function GetPreciseBoundingBox(part As SldWorks.PartDoc) As Variant
    Dim dBox(5) As Double
    Dim vBodies As Variant
    vBodies = part.GetBodies2(swBodyType_e.swSolidBody, True)
    Dim minX As Double
    Dim minY As Double
    Dim minZ As Double
    Dim maxX As Double
    Dim maxY As Double
    Dim maxZ As Double
    If Not IsEmpty(vBodies) Then
        Dim i As Integer
        For i = 0 To UBound(vBodies)
            Dim swBody As SldWorks.Body2
            Set swBody = vBodies(i)
            Dim x As Double
            Dim y As Double
            Dim z As Double
            swBody.GetExtremePoint 1, 0, 0, x, y, z
            If i = 0 Or x > maxX Then maxX = x

            swBody.GetExtremePoint -1, 0, 0, x, y, z
            If i = 0 Or x < minX Then minX = x

            swBody.GetExtremePoint 0, 1, 0, x, y, z
            If i = 0 Or y > maxY Then maxY = y

            swBody.GetExtremePoint 0, -1, 0, x, y, z
            If i = 0 Or y < minY Then minY = y

            swBody.GetExtremePoint 0, 0, 1, x, y, z
            If i = 0 Or z > maxZ Then maxZ = z
            
            swBody.GetExtremePoint 0, 0, -1, x, y, z
            If i = 0 Or z < minZ Then minZ = z
        Next
    End If
    dBox(0) = minX: dBox(1) = minY: dBox(2) = minZ
    dBox(3) = maxX: dBox(4) = maxY: dBox(5) = maxZ
        Debug.Print "minX" & minX
    
    
    Debug.Print "minY" & minY
    Debug.Print "minZ" & minZ
    Debug.Print "maxX" & maxX
    Debug.Print "maxY" & maxY
    Debug.Print "maxZ" & maxZ

    
    GetPreciseBoundingBox = dBox
    
    Debug.Print "essai" & dBox(0)
End Function