Je joins ac-cobra, dans quel but ? Ça se passe plutôt en inverse, et surtout ça va compliquer la publication des plans, sinon la modélisation descendante est elle pas suffisante !?
Oui réduire le poids fait partie du but.
Je veux aussi avoir un fichier « objet complet assemblé » indépendant, complet mais qui ne dépende pas de références externes. Ce qui facilite, partage, stockage, et assure a minima de pouvoir exploiter l’objet quoi qu’il arrive.
Dans mon monde idéal, je programmerais une macro qui se contenterait, depuis un assemblage ouvert, de créer un fichier PRT vierge, d’extraire les arbres de chaque pièces de l’assemblage et de les copier dans le PRT (en renommant items si besoin) mais en modifiant l’origine locale de chaque pièce par l’origine de l’assemblage, pour assurer de garder leur placement conforme à l’assemblage.
C’est une pièce à part que tu enregistrer en dehors de l’assemblage que peux déplacer et là les liens seront rompu…
Alors déjà merci pour l’astuce que je ne connaissais pas et qui me sera forcément utile un jour.
Hélas elle ne répond pas à la demande, mais je comprends la confusion car le mot « fusionner » que j’ai employé n’est pas le plus approprié. Il fallait comprendre « regrouper ».
Je suis un peu perdu, car je ne comprends pas bien le fait d’avoir une pièce avec des corps ou non car celle-ci ne pourra pas être modifiée et le visuel sera pareil qu’un fichier enregistré en prt.
Alors déjà, mon erreur à la reconnaissance des fonctions est causée par la visserie issue de la toolbox. Si je les exclu du prt la reconnaissance se déroule correctement. C’est dommage mais bon, disons que c’est déjà pas mal.
Sauf qu’apparemment il faut lancer manuellement une reconnaissance de fonctions pour chaque objet importé, l’un après l’autre… On ne peut pas faire une reconnaissance multiple ??
Je me suis sans doute mal exprimé mais pour être plus clair, disons que je veux ce que fait « enregistrer ASM sous PRT », sauf que je ne veux pas avoir à passer par d’inutiles reconversions de conversions de géométries, ni une (des!!) reconnaissance de fonctions. Je veux garder fonctions, relations, cotations, noms d’origine. Un bête clonage de l’arbre original de chaque pièce* dans une autre pièce commune, quoi. (encore plus qd je vois le temps qu’il faut pour reconnaître les fonctions et qu’il faut la relancer pour chacune des pièces…, puis les renommer…). Que, dans l’arbre de la pièce commune, les arbres des pièces soient hiérarchisés dans des dossiers individuels du nom des pièces.
On serait plus sur l’outil « joindre » mais sans fusion, juste un ajout de chaque arbre*, tel quel, l’un après l’autre dans la nouvelle pièce cible. Une concaténation sans conversion, du coup. Et toujours, idéalement, dans des dossiers séparés (dans le featureManager hein).
Il faut croire que seule une macro pourra répondre à ces exigences
*quand je parle « d’arbre original » comprenez « l’ensemble des fonctions, plans, etc qui composent la pièce ».
En fait ce que tu souhaites c’est travailler les multiples fonctions des tes pièces de l’assemblage dans une pièce, je sais pas si je me suis bien exprimé
En fait, je voudrais que toutes les pièces d’un assemblage soient « embedded » en l’état dans un seul PRT.
La seule différence visible dans l’arbre étant que l’icône « part » jaune devient de fait une icône « folder » bleue.
Et en effet, du coup ça permettrait d’éditer normalement toutes les « pièces » (leurs fonctions groupées dans des dossiers) depuis la pièce commune.
Je ne crois pas que ce soit possible de faire ça
La seul façon c’est d’anticiper et de construite dans une pièce en multi-corps et ça ne t’aideras pas en ce qui concerne l’allègement de la pièce par rapport à un assemblage car c’est les fonction qui sont lourdes …
Bon courage car il va t’en falloir
Bonjour,
En gros, ce que vous voudriez faire, c’est utiliser la fonction « insérer pièce » mais au lieu d’un part, ce serait un assemblage (impossible avec cette commande) et pouvoir utiliser l’option « propager à partir de la pièce d’origine ». Je précise qu’il faut rompre les lien avec la pièce d’origine pour récupérer l’arbre de construction.
A part avec une macro qui prendrait chaque pièce de l’assemblage une par une et qui utiliserait cette commande, je ne vois pas.
Bon courage à vous
Bonjour @Sylk
Toute la problématique est dans ces deux mots: extraire et copier. Dit autrement: copier/coller…
Balayer l’arbre des composants de l’assemblage pour identifier les pièces « sources » est facilement envisageable, mais à ma connaissance il n’existe pas de procédure du type copier/coller de l’arbre de construction de chaque pièce « source » dans une même pièce « destination ».
Les seules entités « copiables » d’une pièce vers une autre sont les esquisses, les courbes, les surfaces et les corps, pas les fonctions géométriques.
A défaut de concaténation dans une pièce, une autre piste peut être explorée, qui permet de réduire la sauvegarde à un fichier unique: virtualiser tous les composants, c’est à dire les intégrer dans le document d’assemblage.
La logique répond à votre attente, même si le document final est un assemblage et non une pièce.
La fonction « Rendre virtuel » existe dans les API de SolidWorks. Les liens des pièces virtualisées vers les pièces d’origine sont rompus, mais l’arbre de construction est conservé.
Cordialement.
Bonjour @Rim-b
Excellent !! Mais pas parfait… C’est exactement le résultat final attendu, sauf pour le placement.
J’insère une pièce de tôlerie dans la pièce de la tôlerie hôte, mais je ne peux pas la positionner à souhait. Est-il possible de pivoter la tôlerie insérée ou est-on limités à la translation lors de l’insertion uniquement ?
L’idée de départ de passer par un assemblage était principalement pour rendre les positionnements simples, avant que tout ça finisse en un prt.
Bonjour,
Non il y a des fonctions d’assemblages (déplacer avec des contraintes).
Mais très franchement c’est une usine à gaz, vu de ma fenêtre, ce que vous cherchez à faire.
Faut choisir le bon mode au démarrage (assemblage ou pièce dans pièce) car « convertir » par la suite c’est des heures et des heures de boulot. Je ne suis même pas certain qu’une macro y arrive sans générer des erreurs de positionnement ou tout du moins faudra passer des heures sur ce type de développement.
J’utilise souvent la fonction insérer piece et je confirme vos dir cyril, le truc saute au moindre changement dans l’arborescence sw n’aime pas trop jouer avec la barre de reprise,
Pour la copie de fonction avec macro je pense pas non plus, je vois pas comment peut on modifier un perçage où un enlèvement de matière borgne ou à travers tout sans affecté les autres corps !
Bonjour,
L’insertion de pièce dans une pièce fonctionne. Par contre si vous avez plus d’une dizaine de pièces ça risque de très vite être galère à gérer. Si vous voulez que ça fonctionne le mieux est de sûrement pas utiliser les contraintes lors de l’insertion de pièces mais que des positions.
Une piste de solution serait peut être de faire des regroupement de pièces qui vont ensemble (donc faire des sous pièces) et après d’insérer une dizaine de pièces dans une pièce.
NB : Au niveau des reconstructions ça risque d’être coton à gérer dans tous les cas.
Oui je confirme et c’est assez pénalisant quand un client t’envoie un ASM au format STEP par exemple ou autre neutre pour te faire faire une simulation RDM. Sans compter que tu perds au passage toutes les contraintes.
Bon courage
Bonjour.
Merci à tous pour vos réponses très instructives !
Alors, j’ai testé l’insertion de pièce dans une pièce, le fichier pèse 2 fois moins lourd qu’un assemblage avec la même pièce rendue virtuelle.
Que le poids passe du double au simple n’est pas négligeable.
Toutefois, au lu de ce topic, j’ai l’impression que virtualiser les pièces dans un assemblage reste de loin la solution la plus simple, pratique et flexible.
Quel dommage que le fichier pèse le double…
L’astuce des pipiP est effectivement une possibilité intéressante, @froussel
En vérifiant dans lapi, il me semble que c’est jouable:
-
Parcourir les composants un par un
-
Récupérer la position et orientation du composant par rapport à l’origine assemblage.
-
Insérer le composant dans une pièce et rompre le lien .
-
Détecter les nouveaux corps(un peu casse tête ! ) .
-
Appliquer une orientation et un déplacement à ces nouveaux corps
En rompant le lien, les fonctions de la pièce insérée sont récupérés dans l’arborescence, le miracle c’est que SW les appliquent seulement aux nouveaux corps (il modifie les définition et les zones actions de tous les corps vers une sélection automatique😀) ce qui évite le souci que j’ai évoqué précédemment,aussi le lien est rompu l’arborescence et stable,
Le seul bimol que je trouve c’est que ces corps sont positionnés par rapport à l’origine pièce non pas par interactions de contraintes.
Sans dire que l’arborescence vas être très très longue en fonction du nombre de composants et leur complexités
Si joint une description des points
(merci a @Rim-b qui a évoqué la fonction principale)
Assemblage1.zip (355,9 Ko)
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
<< le code est dépourvu de la gestion des erreurs, à tester selon besoin, à modifier le chemin template, api 2022>>