PhilBat Posté(e) le 4 avril 2012 Posté(e) le 4 avril 2012 Bonjour à tous,je voudrais à partir d'un programme crée avec VS2010 (fichier dll)avoir accès temporairement au contenu du dessin DWG courant (faire des zooms par ex.)et revenir à mon programme (en cliquant sur la fenêtre). Autre problème. Comment executer des commandes en synchrone dans AutoCAD (comprends rien surla mise en application de la méthose Acedcommand). A bientôtPhil.
(gile) Posté(e) le 4 avril 2012 Posté(e) le 4 avril 2012 Salut, Je ne comprends pas bien la demande.Ton programme est-il lié à AutoCAD (commande AutoCAD) ou est-ce un exe indépendant ?Dans le deuxième cas, tu ne devrais pas avoir de problème pour faire ce que tu veux dans AutoCAD et revenir à ton programme. Je pencherais donc pour le premier cas et j'imagine que ton programme utilise une fenêtre (Windows.Form).Si c'est bien le cas, il faut que tu ouvres ta fenêtre en mode non modal (modeless) : Application.ShowModelessDialog (Form); Ainsi le focus passera automatiquement de ta fenêtre à la fenêtre AutoCAD quand ton curseur passera de l'une à l'autre (comme avec une palette).Si tu veux agir sur AutoCAD depuis ton programme, il faudra verrouiller le document : using (doc.LockDocument()) { // ici le code qui agit dans AutoCAD } Autre problème. Comment executer des commandes en synchrone dans AutoCAD (comprends rien surla mise en application de la méthose Acedcommand). Je t'ai déjà répondu ici. Exemple pour cercle de centre 10,20 et rayon 10 et un zoom étendu : Command("_circle", new Point3d(10.0, 20.0, 0.0), 10.0); Command("_zoom", "_extents"); Les expressions ci-dessus fonctionneront si le code dans le sujet donné en lien est dans la même classe, sinon si le code est défini dans une autre classe (class Pinvoke par exemple), il faut l'appeler en faisant précéder Command() du nom de la classe et d'un point : Pinvoke.Command(...) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilBat Posté(e) le 5 avril 2012 Auteur Posté(e) le 5 avril 2012 SalutOui c'est bien une application pour AutoCAD (Création d'un fichier dll et chargement avec netload dans AutoCAD). Etant débutant dans VB NET, j'éprouve des difficultés de mise en oeuvre de ta réponse pour les commandessynchrone VB -> AutoCAD une commande simple de fermeture du dessin courant me provoque une erreur comme quoi le dessin est en court d'utilisation Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.CloseAndDiscard() Donc je cherche d'autre moyen d'agir directement sur autoCAD.a+Phil
(gile) Posté(e) le 5 avril 2012 Posté(e) le 5 avril 2012 Difficile d'en dire plus avec aussi peu d'informations. Si la commande qui ouvre ta fenêtre doit agir sur plusieurs documents, il faut que tu ajoutes CommandFlags.Session à l'attribut CommandMethod. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilBat Posté(e) le 5 avril 2012 Auteur Posté(e) le 5 avril 2012 La routine dévelloppée sous VS2010 fait apparaitre une fenêtre (FORM).à partir d'un bouton de celle-ci (ou tout autre moyen), je veux commuter sur AutoCAD qui est lui aussien exécution (celle lui qui lance ma routine) pour éventuellement faire des zoomsafin de vérifier de visu le contenu du dessin courant. Une fois fini, je veux avoir la possibilitéde revenir dans la fenêtre de ma routine (qui était toujours visible et en attente) Voici le code en VBA qui illustre la manière pour l'évènement click du bouton Private Sub tglPlan_Click() If tglPlan.Value Then frmPuis.Hide frModal = Not (tglPlan.Value) If frModal Then frmPuis.Show (vbModal) Else frmPuis.Show (vbModeless) End If End If End Sub je voudrai pouvoir en faire autant sous vb net Je sais pas si cela est suffisant pour éclaicir mon problème. Phil.
(gile) Posté(e) le 5 avril 2012 Posté(e) le 5 avril 2012 Non ça n'est pas vraiment éclairant*. Dans tous les cas, essaye d'oublier le VBA, .NET est un environnement complètement différent (même si la syntaxe du VB.net ressemble à celle du VBA, voir ce sujet). Pour faire ce que tu veux, utilise plutôt une boite modeless qui restera visible et te permettra d'accéder à AutoCAD sans avoir à cliquer sur un bouton. * si je comprends bien ton code, frModal sera toujours False puisque tglPlan.Value est True quand frModal est assignée, donc c'est toujours frmPuis.Show (vbModeless) qui sera exécutée.Autrement dit ton code VBA pourrait tout simplement être ça :Private Sub tglPlan_Click() If tglPlan.Value Then frmPuis.Hide frModal = False frmPuis.Show (vbModeless) End If End Sub Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilBat Posté(e) le 17 avril 2012 Auteur Posté(e) le 17 avril 2012 Bonjour,après X essais, je n'arrive toujours pas à mettre en oeuvre une commandesynchrone avec AutoCAD à partir d'une fenêtre form en modeless.le but c'est de créer :- un calque "-GpO_parcours" si nécessaire- une poligne (avec 5 points max.)- inserer un bloc sur ces points (avec attribut de valeur 1 à 5).Voici le code : Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim ed As Editor = acDoc.Editor Dim Db As Database = acDoc.Database Dim AcCalque As String If PtRefX(0) = 0 Then Exit Sub ' mémo calque courant AcCalque = ThisDrawing.Application.ActiveDocument.ActiveLayer.Name Using lockDoc As DocumentLock = acDoc.LockDocument() '' verrouille le document Using Tr As Transaction = Db.TransactionManager.StartTransaction() '' Open the Layer table for read Dim acLyrTbl As LayerTable acLyrTbl = Tr.GetObject(Db.LayerTableId, OpenMode.ForRead) Dim sLayerName As String = "-GpO_Parcours" If acLyrTbl.Has(sLayerName) = False Then Dim acLyrTblRec As LayerTableRecord = New LayerTableRecord() '' Assign the layer the ACI color 1 and a name acLyrTblRec.Color = Color.FromColorIndex(ColorMethod.ByAci, 1) acLyrTblRec.Name = sLayerName '' Upgrade the Layer table for write acLyrTbl.UpgradeOpen() '' Append the new layer to the Layer table and the transaction acLyrTbl.Add(acLyrTblRec) Tr.AddNewlyCreatedDBObject(acLyrTblRec, True) End If '' Set the layer -GpO_Parcours current Db.Clayer = acLyrTbl(sLayerName) If PtRefX(0) <> 0 And PtRefY(0) <> 0 And PtRefX(1) <> 0 And PtRefY(1) <> 0 And _ PtRefX(2) <> 0 And PtRefY(2) <> 0 And PtRefX(3) <> 0 And PtRefY(3) <> 0 And _ PtRefX(4) <> 0 And PtRefY(4) <> 0 And PtRefX(5) <> 0 And PtRefY(5) <> 0 Then TemPoly = True EffPtRefDess() Pinvoke.Command("_pline", New Point3d(PtRefX(0), PtRefY(0), 0.0#), New Point3d(PtRefX(1), PtRefY(1), 0.0#), _ New Point3d(PtRefX(2), PtRefY(2), 0.0#), New Point3d(PtRefX(3), PtRefY(3), 0.0#), _ New Point3d(PtRefX(4), PtRefY(4), 0.0#), New Point3d(PtRefX(5), PtRefY(5), 0.0#)) End If If PtRefX(0) <> 0 And PtRefY(0) <> 0 And PtRefX(1) <> 0 And PtRefY(1) <> 0 And _ PtRefX(2) <> 0 And PtRefY(2) <> 0 And PtRefX(3) <> 0 And PtRefY(3) <> 0 And _ PtRefX(4) <> 0 And PtRefY(4) <> 0 And PtRefX(5) = 0 And PtRefY(5) = 0 Then TemPoly = True EffPtRefDess() Pinvoke.Command("_pline", New Point3d(PtRefX(0), PtRefY(0), 0.0#), New Point3d(PtRefX(1), PtRefY(1), 0.0#), _ New Point3d(PtRefX(2), PtRefY(2), 0.0#), New Point3d(PtRefX(3), PtRefY(3), 0.0#), _ New Point3d(PtRefX(4), PtRefY(4), 0.0#)) End If If PtRefX(0) <> 0 And PtRefY(0) <> 0 And PtRefX(1) <> 0 And PtRefY(1) <> 0 And _ PtRefX(2) <> 0 And PtRefY(2) <> 0 And PtRefX(3) <> 0 And PtRefY(3) <> 0 And _ PtRefX(4) = 0 And PtRefY(4) = 0 And PtRefX(5) = 0 And PtRefY(5) = 0 Then TemPoly = True EffPtRefDess() Pinvoke.Command("_pline", New Point3d(PtRefX(0), PtRefY(0), 0.0#), New Point3d(PtRefX(1), PtRefY(1), 0.0#), _ New Point3d(PtRefX(2), PtRefY(2), 0.0#), New Point3d(PtRefX(3), PtRefY(3), 0.0#)) End If If PtRefX(0) <> 0 And PtRefY(0) <> 0 And PtRefX(1) <> 0 And PtRefY(1) <> 0 And _ PtRefX(2) <> 0 And PtRefY(2) <> 0 And PtRefX(3) = 0 And PtRefY(3) = 0 And _ PtRefX(4) = 0 And PtRefY(4) = 0 And PtRefX(5) = 0 And PtRefY(5) = 0 Then TemPoly = True EffPtRefDess() Pinvoke.Command("_pline", New Point3d(PtRefX(0), PtRefY(0), 0.0#), New Point3d(PtRefX(1), PtRefY(1), 0.0#), _ New Point3d(PtRefX(2), PtRefY(2), 0.0#)) End If If PtRefX(0) <> 0 And PtRefY(0) <> 0 And PtRefX(1) <> 0 And PtRefY(1) <> 0 And _ PtRefX(2) = 0 And PtRefY(2) = 0 And PtRefX(3) = 0 And PtRefY(3) = 0 And _ PtRefX(4) = 0 And PtRefY(4) = 0 And PtRefX(5) = 0 And PtRefY(5) = 0 Then TemPoly = True EffPtRefDess() Pinvoke.Command("_pline", New Point3d(PtRefX(0), PtRefY(0), 0.0#), New Point3d(PtRefX(1), PtRefY(1), 0.0#)) End If If PtRefX(0) <> 0 And PtRefY(0) <> 0 Then Pinvoke.Command("-i", "PointBase.dwg", New Point3d(PtRefX(0), PtRefY(0), 0.0#), 5, 5, 0) For I = 1 To 5 If PtRefX(I) <> 0 And PtRefY(I) <> 0 Then Pinvoke.Command("-i", "Pointref.dwg", New Point3d(PtRefX(I), PtRefY(I), 0.0#), 5, 5, 0, I.ToString) End If Next End If Db.Clayer = acLyrTbl(AcCalque) Tr.Commit() End Using ThisDrawing.Application.Update() End Using Mais je ne vois rien sur l'écran de autocad même une fois la fenêtre form quitter.Merci à tousnota: la routine 'EffPtRefDess' efface toutes les entitées du calque '-GpO_Parcours' Phil
(gile) Posté(e) le 17 avril 2012 Posté(e) le 17 avril 2012 Salut, Il faut essayer d'éviter d'utiliser les commandes AutoCAD, créer une polyligne n'est pas très difficile, insérer un bloc avec attributs un peu plus, mais tu trouveras ici des exemples progressifs. Un exemple inspiré de ton code. : J'ai extrait une méthode pour les insertions de blocs qui s'utilise comme la méthode COM InsertBlock. C# private void button1_Click(object sender, EventArgs e) { Document doc = AcAp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; Point3d[] pts = { new Point3d(100.0,200,0.0), new Point3d(200.0,100,0.0), new Point3d(350.0,150,0.0), new Point3d(400.0,300,0.0), new Point3d(600.0,200,0.0) }; Plane plane = new Plane(); using (doc.LockDocument()) using (Transaction tr = db.TransactionManager.StartTransaction()) { Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView(); BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord mSpace = (BlockTableRecord)tr.GetObject(bt[blockTableRecord.ModelSpace], OpenMode.ForWrite); LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead); // Création du calque s'il n'existe pas if (!lt.Has("-GpO_Parcours")) { using (LayerTableRecord ltr = new LayerTableRecord()) { ltr.Name = "-GpO_Parcours"; ltr.Color = AcColor.FromColorIndex(ColorMethod.ByAci, 1); lt.UpgradeOpen(); lt.Add(ltr); tr.AddNewlyCreatedDBObject(ltr, true); } } // Création de la polyligne using (Polyline pline = new Polyline()) { for (int i = 0; i < pts.Length; i++) { pline.AddVertexAt(i, pts[i].Convert2d(plane), 0.0, 0.0, 0.0); } pline.Layer = "-GpO_Parcours"; mSpace.AppendEntity(pline); tr.AddNewlyCreatedDBObject(pline, true); } // Insertion des blocs if (!bt.Has("Pointref")) return; for (int i = 0; i < pts.Length; i++) { BlockReference br = InsertBlock(mSpace, pts[i], "Pointref", new Scale3d(5.0), 0.0); br.Layer = "-GpO_Parcours"; // Définition de la valeur de l'attribut AttributeReference att = (AttributeReference)tr.GetObject(br.AttributeCollection[0], OpenMode.ForWrite); att.TextString = i.ToString(); } tr.Commit(); } } public BlockReference InsertBlock(BlockTableRecord btr, Point3d insPt, string blockName, Scale3d scale, double rotation) { Database db = btr.Database; Transaction tr = db.TransactionManager.TopTransaction; BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); // Insertion du bloc, mise à l'échelle et rotation BlockReference br = new BlockReference(insPt, bt[blockName]) { ScaleFactors = scale, Rotation = rotation }; br.RecordGraphicsModified(true); btr.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); // Ajout des références d'attribut avec les valeurs par défaut copiées depuis les définitions d'attribut BlockTableRecord def = (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead); foreach (ObjectId id in def) { if (id.ObjectClass.Name == "AcDbAttributeDefinition") { AttributeDefinition attDef = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead); AttributeReference attRef = new AttributeReference(); attRef.SetAttributeFromBlock(attDef, br.BlockTransform); attRef.TextString = attDef.TextString; br.AttributeCollection.AppendAttribute(attRef); tr.AddNewlyCreatedDBObject(attRef, true); } } return br; } VB Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim pts As Point3d() = { _ New Point3d(100.0, 200, 0.0), _ New Point3d(200.0, 100, 0.0), _ New Point3d(350.0, 150, 0.0), _ New Point3d(400.0, 300, 0.0), _ New Point3d(600.0, 200, 0.0)} Dim plane As New Plane() Using doc.LockDocument() Using tr As Transaction = db.TransactionManager.StartTransaction() Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView() Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) Dim mSpace As BlockTableRecord = DirectCast(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord) Dim lt As LayerTable = DirectCast(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable) ' Création du calque s'il n'existe pas If Not lt.Has("-GpO_Parcours") Then Using ltr As New LayerTableRecord() ltr.Name = "-GpO_Parcours" ltr.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(ColorMethod.ByAci, 1) lt.UpgradeOpen() lt.Add(ltr) tr.AddNewlyCreatedDBObject(ltr, True) End Using End If ' Création de la polyligne Using pline As New Polyline() For i As Integer = 0 To pts.Length - 1 pline.AddVertexAt(i, pts(i).Convert2d(plane), 0.0, 0.0, 0.0) Next pline.Layer = "-GpO_Parcours" mSpace.AppendEntity(pline) tr.AddNewlyCreatedDBObject(pline, True) End Using ' Insertion des blocs If Not bt.Has("Pointref") Then Return End If For i As Integer = 0 To pts.Length - 1 Dim br As BlockReference = InsertBlock(mSpace, pts(i), "Pointref", New Scale3d(5.0), 0.0) br.Layer = "-GpO_Parcours" ' Définition de la valeur de l'attribut Dim att As AttributeReference = DirectCast(tr.GetObject(br.AttributeCollection(0), OpenMode.ForWrite), AttributeReference) att.TextString = i.ToString() Next tr.Commit() End Using End Using End Sub Public Function InsertBlock(ByVal btr As BlockTableRecord, ByVal insPt As Point3d, ByVal blkName As String, _ ByVal scale As Scale3d, ByVal rotation As Double) _ As BlockReference Dim db As Database = btr.Database Dim tr As Transaction = db.TransactionManager.TopTransaction Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) ' Insertion du bloc, mise à l'échelle et rotation Dim br As BlockReference = New BlockReference(insPt, bt(blkName)) br.ScaleFactors = scale br.Rotation = rotation br.RecordGraphicsModified(True) btr.AppendEntity(br) tr.AddNewlyCreatedDBObject(br, True) ' Ajout des références d'attribut avec les valeurs par défaut copiées depuis les définitions d'attribut Dim def As BlockTableRecord = DirectCast(tr.GetObject(bt(blkName), OpenMode.ForRead), BlockTableRecord) If def.HasAttributeDefinitions Then For Each id As ObjectId In def If id.ObjectClass.Name = "AcDbAttributeDefinition" Then Dim attDef = DirectCast(tr.GetObject(id, OpenMode.ForRead), AttributeDefinition) Dim attRef As New AttributeReference() attRef.SetAttributeFromBlock(attDef, br.BlockTransform) attRef.TextString = attDef.TextString br.AttributeCollection.AppendAttribute(attRef) tr.AddNewlyCreatedDBObject(attRef, True) End If Next End If Return br End Function Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilBat Posté(e) le 19 avril 2012 Auteur Posté(e) le 19 avril 2012 Merci pour ces informations,indispensables pour moi, car il est vrai que sans ce forumil me serait très difficile de mettre en oeuvre mon programme.La documentation sur ce sujet (vb net pour autocad) est assez "lite"en générale.Même Autodesk donne quelques exemples mais n'aborde pas tous les cas de figure Concernant mon accès au dwg depuis une fenêtre "form" (modeless), j'avais compris qu'ilfallait verrouiller le DWG puis utiliser "les commandes autocad (acedcommand)", celane marchais pas malgré toutes tentatives. Gile, Ta dernière solution marche enfin... :D B) .... ouf Mais je ne suis pas au bout de mes peines, j'ai encore du travail à fairepour finaliser mon programme.a+Phil
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant