Een assembly converteren naar een zelfstandig bestand

Hallo @Rim-b
Uitstekend!! Maar niet perfect... Dit is precies het verwachte eindresultaat, behalve de plaatsing.

Ik plaats een plaatwerkonderdeel in het hostplaatwerk, maar ik kan het niet naar wens positioneren. Is het mogelijk om het ingebrachte plaatwerk te roteren of zijn we beperkt tot vertaling alleen tijdens het invoegen?

Het aanvankelijke idee om een assemblage te doorlopen was vooral om de positionering eenvoudig te maken, voordat het allemaal in een lening belandde.

Hallo

Nee, er zijn montagefuncties (verplaatsen met beperkingen).
Maar eerlijk gezegd is het een gasfabriek, gezien vanuit mijn raam, wat je probeert te doen.
Je moet bij het opstarten de juiste modus kiezen (assemblage of onderdeel in een deel) want "converteren" achteraf is uren en uren werk. Ik weet niet eens zeker of een macro het kan doen zonder positioneringsfouten te genereren of in ieder geval uren aan dit soort ontwikkeling te moeten besteden.

2 likes

Ik gebruik vaak de functie voor het invoegen van een deel en ik bevestig je dir cyril, het ding springt bij de minste verandering in de boom sw houdt er niet van om te veel met de herstelbalk te spelen,
Voor de kopie van een functie met macro denk ik ook niet, ik zie niet in hoe je een gat of een verwijdering van blind materiaal of door alles heen kunt wijzigen zonder de andere lichamen te beïnvloeden!

3 likes

Hallo

Het invoegen van een onderdeel in een onderdeel werkt. Aan de andere kant, als je meer dan een dozijn onderdelen hebt, kan het heel snel een gedoe zijn om te beheren. Als u wilt dat het werkt, kunt u het beste waarschijnlijk geen beperkingen gebruiken bij het invoegen van onderdelen, maar alleen posities.
Een mogelijke oplossing zou misschien zijn om groeperingen te maken van stukken die bij elkaar passen (dus substukken maken) en dan een dozijn stukken in een kamer in te voegen.

NB: Wat de reconstructie betreft, kan het in ieder geval moeilijk te beheren zijn.

1 like

Ja, ik bevestig het en het is behoorlijk bestraffend als een klant je bijvoorbeeld een ASM in STEP-formaat of een ander neutraal formaat stuurt om je een RDM-simulatie te laten doen. Om nog maar te zwijgen van het feit dat je alle beperkingen in het proces verliest.

Succes :cold_face:

2 likes

Hallo.
Dank u allen voor uw zeer informatieve antwoorden!

Dus ik heb het invoegen van een onderdeel in een onderdeel getest, het bestand weegt 2 keer minder dan een assemblage met hetzelfde onderdeel virtueel gemaakt.
Het feit dat het gewicht van dubbel naar enkel gaat, is niet te verwaarlozen.

Bij het lezen van dit onderwerp heb ik echter de indruk dat het virtualiseren van de onderdelen in een assemblage verreweg de eenvoudigste, meest praktische en flexibele oplossing blijft.
Wat jammer dat de map twee keer zoveel weegt...
De plastruc is inderdaad een interessante mogelijkheid, @froussel

Als ik lapi incheck, lijkt het mij dat het speelbaar is:

  1. Blader één voor één door de componenten

  2. Haal de positie en oriëntatie van het onderdeel op ten opzichte van de oorsprong van de assemblage.

  3. Plaats het onderdeel in een onderdeel en verbreek de schakel.

  4. Het detecteren van nieuwe lichamen (een beetje hoofdpijn!) .

  5. Pas oriëntatie en verplaatsing toe op deze nieuwe lichamen

Door de link te verbreken, worden de functies van het ingevoegde deel hersteld in de boom, het wonder is dat SW ze alleen toepast op nieuwe lichamen (het wijzigt de definitie en actiegebieden van alle lichamen naar een automatische😀 selectie) die het probleem vermijdt dat ik eerder noemde, dus de link is verbroken de boom en stabiel,

Het enige verschil dat ik vind, is dat deze lichamen zijn gepositioneerd ten opzichte van de oorsprong van het deel, niet door stressinteracties.
Om niet te zeggen dat de boomstructuur heel, heel lang zal zijn, afhankelijk van het aantal componenten en hun complexiteit

3 likes

Indien bijgevoegd een beschrijving van de punten
(Met dank aan @Rim-B die de hoofdfunctie noemde)






Assemblage1.zip (355.9 KB)

Option Explicit

Dim swApp As Object
Dim swmodel As ModelDoc2
Dim swpart As PartDoc
Dim swassembly As AssemblyDoc
Dim swMathUtils As SldWorks.MathUtility
Dim featmgr As FeatureManager
Dim pbodies As Variant
Dim selmgr As SelectionMgr
Const PI As Double = 3.14159265359


Sub main()

    Set swApp = Application.SldWorks
    Set swMathUtils = swApp.GetMathUtility
    Set swassembly = swApp.ActiveDoc
    Set swmodel = swApp.NewDocument("C:\ProgramData\SOLIDWORKS\SOLIDWORKS 2022\templates\Pièce.PRTDOT", 0, 0, 0)
    Set swpart = swmodel
    Set featmgr = swmodel.FeatureManager
    Set selmgr = swmodel.SelectionManager
    Dim comp As Component2
    Dim vcomp As Variant, vc As Variant
    vcomp = swassembly.GetComponents(False)
        
    For Each vc In vcomp
        Set comp = vc
        Dim pos As Variant
        pos = get_position(comp)
        
        pbodies = swpart.GetBodies2(0, False)
        swpart.InsertPart3 comp.GetPathName, 512, comp.ReferencedConfiguration()
        select_bodies get_bodies(swpart, pbodies)
        featmgr.InsertMoveCopyBody2 0, 0, 0, 0, 0, 0, 0, pos(5), pos(4), pos(3), False, 1
        
        select_bodies get_bodies(swpart, pbodies)
        featmgr.InsertMoveCopyBody2 pos(0), pos(1), pos(2), 0, 0, 0, 0, 0, 0, 0, False, 1
    Next
End Sub

Function get_position(comp As Component2) As Variant
    Dim pos(5) As Variant
    Dim swTransform As SldWorks.MathTransform
    Set swTransform = comp.Transform2
    
    Dim r11 As Double, r12 As Double, r13 As Double
    Dim r21 As Double, r22 As Double, r23 As Double
    Dim r31 As Double, r32 As Double, r33 As Double
    
    Dim r41 As Double, r42 As Double, r43 As Double
    Dim r44 As Double
    
    r41 = swTransform.ArrayData(9)
    r42 = swTransform.ArrayData(10)
    r43 = swTransform.ArrayData(11)
    r44 = swTransform.ArrayData(12)
    pos(0) = r41 * r44
    pos(1) = r42 * r44
    pos(2) = r43 * r44
        
    Set swTransform = swTransform.Inverse
    r11 = swTransform.ArrayData(0)
    r12 = swTransform.ArrayData(1)
    r13 = swTransform.ArrayData(2)
    
    r21 = swTransform.ArrayData(3)
    r22 = swTransform.ArrayData(4)
    r23 = swTransform.ArrayData(5)
    
    r31 = swTransform.ArrayData(6)
    r32 = swTransform.ArrayData(7)
    r33 = swTransform.ArrayData(8)
    
    If r13 < 1 Then
        If r13 > -1 Then
            pos(3) = atan2(-r23, r33)
            pos(4) = asin(r13)
            pos(5) = atan2(-r12, r11)
        Else
            pos(3) = -atan2(r21, r22)
            pos(4) = -PI / 2
            pos(5) = 0
        End If
    Else
        pos(3) = atan2(r21, r22)
        pos(4) = PI / 2
        pos(5) = 0
    End If

    get_position = pos
    
End Function

Function get_bodies(part As PartDoc, pbodies As Variant) As Variant
    Dim cbodies As Variant, bod As Variant, bod1 As Variant
    Dim vbodies() As Variant
    Dim row As Integer
    row = 0
    Dim isnew As Boolean
    Dim body As Body2
    Dim body1 As Body2
    cbodies = part.GetBodies2(0, False)
    If Not IsEmpty(pbodies) Then
        For Each bod In cbodies
            isnew = True
            Set body = bod
            For Each bod1 In pbodies
                Set body1 = bod1
                If body.Name = body1.Name Then
                    isnew = False
                End If
            Next
            If isnew = True Then
                ReDim Preserve vbodies(row)
                Set vbodies(row) = body
                row = row + 1
            End If
        Next
        Dim v As Variant
        get_bodies = vbodies
    Else
        get_bodies = cbodies
    End If
End Function

Sub select_bodies(bodies As Variant)
    Dim seldata As SelectData
    Dim bod As Variant
    Dim body As Body2
    Set seldata = selmgr.CreateSelectData
    seldata.Mark = 1
    swmodel.ClearSelection2 True
    If Not IsEmpty(bodies) Then
        For Each bod In bodies
            Set body = bod
            body.Select2 True, seldata
        Next
    End If
End Sub

Function atan2(Y As Double, X As Double) As Double
    If X > 0 Then
        atan2 = Atn(Y / X)
    ElseIf X < 0 Then
        atan2 = Sgn(Y) * (PI - Atn(Abs(Y / X)))
    ElseIf Y = 0 Then
        atan2 = 0
    Else
        atan2 = Sgn(Y) * PI / 2
    End If
End Function

Function asin(X As Double) As Double
    If Abs(X) = 1 Then
        asin = X * PI / 2
    Else
        asin = Atn(X / Sqrt(1 - X * X))
    End If
End Function

<< de code vrij is van foutafhandeling, test indien nodig, wijzig de padsjabloon, API 2022>>

2 likes

Hallo @Lynkoa15
BEDANKT! Deze macro ziet er geweldig uit. Ik test het zo snel mogelijk.

Slechts één ding. Op een van mijn macro's in het proces van dev' Ik moest view rotaties toepassen, en om een zo nauwkeurig mogelijke PI-waarde te hebben, schreef ik dit:

Dim DtR# '(DegToRad)
DtR = (4 * Atn(1)) / 180   ' "Constante" de conversion degrés en radians (Pi/180)

Deze code krijgt PI en deelt deze door 180 om de graden te veranderen in radialen.
(Bijvoorbeeld, (3 * DtR) converteert 3 graden naar radialen)

Kortom, om een "perfecte" PI in VBA te hebben heb je deze code nodig:

Dim PI# '(THE_number)
PI = (4 * Atn(1))   ' "Constante" Pi calculée

Als ik "perfect" zeg, is dat uiteraard binnen de decimale limiet van het dubbele (#) type.

Natuurlijk is er een voordeel aan het gebruik van een constante, zolang je de eerste 14/15 cijfers achter de komma van pi onthoudt (3,14159265358979)

1 like