Aller au contenu

Accès au DWG depuis VB NET


Messages recommandés

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 sur

la mise en application de la méthose Acedcommand).

 

A bientôt

Phil.

Lien vers le commentaire
Partager sur d’autres sites

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 sur

la 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

Lien vers le commentaire
Partager sur d’autres sites

Salut

Oui 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 commandes

synchrone 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

Lien vers le commentaire
Partager sur d’autres sites

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 aussi

en exécution (celle lui qui lance ma routine) pour éventuellement faire des zooms

afin 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.

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines après...

Bonjour,

après X essais, je n'arrive toujours pas à mettre en oeuvre une commande

synchrone 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 à tous

nota: la routine 'EffPtRefDess' efface toutes les entitées du calque '-GpO_Parcours'

Phil

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

Merci pour ces informations,

indispensables pour moi, car il est vrai que sans ce forum

il 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'il

fallait verrouiller le DWG puis utiliser "les commandes autocad (acedcommand)", cela

ne 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 à faire

pour finaliser mon programme.

a+

Phil

Lien vers le commentaire
Partager sur d’autres sites

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 compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité