Aller au contenu

.NET SCU et Affichage dans Fenêtre


Messages recommandés

Bonjour,

 

Je travaille (...toujours pour ceux qui suivent ;) )sur un programme de création de plan automatique.

 

J'ai précedemment défini des SCU nommés, pour chaque planche, par rapport au numéro de tronçon, de segment et d'alternance,une présentation nommée et une classe GRD comportant l'ensemble des informations de positionnements (et autre) de chaque planche

 

Je bloque sur la partie de code (.NET pour moi mais une solution C# conviendra également) servant à orienter la vue dans la fenêtre par rapport au SCU (l'équivalent de Affichage / Point de Vue 3D / SCU courant) :blink: :(

 

J'ai regardé sur differents forums ainsi que dans la bible (AutoCAD .NET Developper's Guide) sans pouvoir être orienté (un minimum) sur ce sujet.

 

Quelqu'un saurait-il me conseillé?

 

Par avance merci... ;)

 

Hyppolight

 

Mon code actuel est le suivant:

 

 'Mise en forme de la fenêtre : gestion SCU / echelle
   Public Sub MISE_EN_FORME_FENETRE_FUN(TRONCON As String, SEGMENT As String, ALT As String, NomLayout As String, GRD As clGRD)

       Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
       Dim db As Database = doc.Database
       Dim ed As Editor = doc.Editor
       Dim layId As ObjectId
       Dim lo As Layout
       Dim loName As String

       Dim tilemode As Short = CShort(AcadAp.GetSystemVariable("TILEMODE"))
       Dim cvPort As Short = CShort(AcadAp.GetSystemVariable("CVPORT"))

       Using doclok As DocumentLock = doc.LockDocument()

           Using tr As Transaction = doc.Database.TransactionManager.StartTransaction

               Try

                   Dim laydic As DBDictionary = DirectCast(tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead, False), DBDictionary)

                   For Each dentry As DictionaryEntry In laydic

                       layId = DirectCast(dentry.Value, ObjectId)
                       lo = DirectCast(tr.GetObject(layId, OpenMode.ForRead), Layout)
                       loName = lo.LayoutName

                       If loName = NomLayout Then

                           Dim Coll As ObjectIdCollection = CollectVieports(lo, doc)

                           'Une seule fenête par présentation à ce moment là
                           Dim VP_ID As ObjectId = Coll(0)

                           Dim r As BlockTableRecord = TryCast(tr.GetObject(lo.BlockTableRecordId, OpenMode.ForRead), BlockTableRecord)

                           For Each obj As ObjectId In r

                               Dim dbobj As DBObject = tr.GetObject(obj, OpenMode.ForRead)
                               Dim vp As DatabaseServices.Viewport = TryCast(dbobj, DatabaseServices.Viewport)

                               If vp IsNot Nothing Then

                                   If vp.ObjectId = VP_ID Then

                                       vp.UpgradeOpen()

                                       vp.On = True
                                       vp.Visible = True

                                       ' Set the new viewport current via an imported ObjectARX function
                                       acedSetCurrentVPort(vp.UnmanagedObject)

                                       ' Activate model space in the viewport
                                       ed.SwitchToModelSpace()

                                       'Définition du SCU associé à la planche
                                       Dim SCU_NAME As String = "SCU_T" & TRONCON & "_S" & SEGMENT & "_A" & ALT

                                       Dim utb As UcsTable = CType(tr.GetObject(db.UcsTableId, OpenMode.ForRead), UcsTable)

                                       If utb.Has(SCU_NAME) Then
                                           Dim itbr As UcsTableRecord = CType(tr.GetObject(utb.Item(SCU_NAME), OpenMode.ForRead), UcsTableRecord)
                                           Dim ucsMat As Matrix3d = Matrix3d.AlignCoordinateSystem( _
                                           Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, _
                                           itbr.Origin, itbr.XAxis, itbr.YAxis, itbr.XAxis.CrossProduct(itbr.YAxis))
                                           ed.CurrentUserCoordinateSystem = ucsMat
                                       End If

                                       'vp.UcsIconAtOrigin = True
                                       'vp.UcsIconVisible = True
                                       'vp.UcsFollowModeOn = True

                                       'vp.SetUcs(utb.Item(SCU_NAME))

                                       '######  PARTIE MANQUANTE #####
                                       '         ORIENTER / SCU     

                                       Exit For

                                   End If

                               End If

                           Next

                           Exit For

                       Else

                       End If
                   Next

               Catch ex As System.Exception
                   MsgBox(ex.ToString)
                   ed.WriteMessage(vbLf & ex.Message & vbLf & ex.StackTrace)
               End Try

               tr.Commit()
               'tr.Dispose()
               ed.Regen()

           End Using 'tr

       End Using 'DocumentLock

   End Sub

   'Listing des fenêtres dans une présentation définie
   Function CollectVieports(ByRef lo As Layout, ByRef doc As Document) As ObjectIdCollection
       Dim db As Database = doc.Database
       Dim Btr As BlockTableRecord
       Dim vp As DatabaseServices.Viewport
       Dim oidcol As ObjectIdCollection = New ObjectIdCollection()
       Dim notpvp As Boolean 'don't include the general layout vp
       Using trans As Transaction = db.TransactionManager.StartTransaction()
           Btr = DirectCast(trans.GetObject(lo.BlockTableRecordId, OpenMode.ForRead), BlockTableRecord)
           For Each oid As ObjectId In Btr
               vp = TryCast(trans.GetObject(oid, OpenMode.ForRead), DatabaseServices.Viewport)
               If Not vp Is Nothing Then
                   If notpvp Then oidcol.Add(oid)
                   notpvp = True
               End If

           Next
       End Using
       Return oidcol
   End Function

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

Je travaille (...toujours pour ceux qui suivent ;) )sur un programme de création de plan automatique.

 

 

 

Bonjour, pas de faux espoir: je suis incapable de t'aider ! mais je suis curieux par rapport à ton programme.

Il y-a-t-il un sujet dans lequel tu expliques comment cela va fonctionner et à qui ça s'adresse ?

 

Bonne journée

Autocad Map 3D 2024 - Covadis version 18.1 - Windows Onze

"Si j'avais du lard je vous ferais une omelette au lard mais j'ai pas d'oeuf..."
Coluche

Lien vers le commentaire
Partager sur d’autres sites

Bonjour, pas de faux espoir: je suis incapable de t'aider ! mais je suis curieux par rapport à ton programme.

Il y-a-t-il un sujet dans lequel tu expliques comment cela va fonctionner et à qui ça s'adresse ?

 

Bonne journée

 

 

Bonjour,

 

C'est un peu compliqué à expliquer en quelques phrases mais voilà:

 

J'ai créer des blocs dynamiques pour la plupart de mes élements mais pour cet exemple je parle de GRD.

(GRD = contour de carroyage dans l'espace papier)

 

Chaque future planche de l'espace papier à son GRD associé dans l'espace objet et je récupère les propriétés dynamiques de mon bloc pour mettre à jour les informations du cartouche, gérer les propriétés d'affichage des calques dans les fenêtres et donc point sur lequel je bloque : orientation du plan / SCU + point de vue 3D courant + zoom par rapport aux contours de mon GRD...

 

Ce programme est interne à l'entrepise et est destiné (pour l'instant...) à un client spécifique

 

Cette partie de plan automatique est la finalisation d'un programme plus vaste (un peu comme COVADIS mais spécifique à un client précis).

 

J'espère avoir répondu à tes attentes..

 

Hyppolight

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Pour modifier la vue dans une fenêtre, il faut jouer sur les propriétés ViewDirection et TwistAngle de l'objet viewport.

Ceci peut se faire indépendamment du SCU (autrement dit, on n'est pas obligé de modifier le SCU dans la fenêtre pour en changer la vue). Comme les données sont stockées dans un SCU nommé on pourrait simplement récupérer ces données.

 

        private void SetUcsToViewport (Document doc, string layoutName, string ucsName)
       {
           var db = doc.Database;
           var ed = doc.Editor;
           using (var tr = db.TransactionManager.StartTransaction())
           {
               var layoutDict = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
               if (!layoutDict.Contains(layoutName))
               {
                   ed.WriteMessage($"\nPrésentation '{layoutName}' introuvable.");
                   return;
               }
               var ucsTable = (UcsTable)tr.GetObject(db.UcsTableId, OpenMode.ForRead);
               if (!ucsTable.Has(ucsName))
               {
                   ed.WriteMessage($"\nSCU nommé '{ucsName}' introuvable.");
                   return;
               }
               var layout = (Layout)tr.GetObject(layoutDict.GetAt(layoutName), OpenMode.ForRead);
               var btr = (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForRead);

               // récupérer la fenêtre de la présention
               var viewports = btr.Cast<ObjectId>()
                   .Where(id => id.ObjectClass.DxfName == "VIEWPORT")
                   .Select(id => (Viewport)tr.GetObject(id, OpenMode.ForRead))
                   .Where(vp => vp.Number != 1);
               if (!viewports.Any())
               {
                   ed.WriteMessage($"\nAucune fenêtre dans la présentation '{layoutName}'.");
                   return;
               }
               LayoutManager.Current.CurrentLayout = layoutName;
               var viewport = viewports.First();

               // récupérer le SCU nommé
               var ucsRecord = (UcsTableRecord)tr.GetObject(ucsTable[ucsName], OpenMode.ForRead);
               var zAxis = ucsRecord.XAxis.CrossProduct(ucsRecord.YAxis);

               // affecter le SCU à la fenêtre (pas indispensable pour modifier la vue)
               ed.SwitchToModelSpace();
               Application.SetSystemVariable("CVPORT", viewport.Number);
               ed.CurrentUserCoordinateSystem = Matrix3d.AlignCoordinateSystem(
                   Point3d.Origin, Vector3d.XAxis, Vector3d.XAxis, Vector3d.ZAxis,
                   ucsRecord.Origin, ucsRecord.XAxis, ucsRecord.YAxis, zAxis);
               ed.SwitchToPaperSpace();

               // modifier la vue dans la fenêtre
               viewport.UpgradeOpen();
               viewport.ViewDirection = zAxis;
               viewport.TwistAngle = -ucsRecord.XAxis.AngleOnPlane(new Plane(Point3d.Origin, zAxis));

               tr.Commit();
           }
       }

  • Upvote 1

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Bonjour Gilles,

 

Merci de t'être prenché sur la question et de me proposé un morceau de code commenté... et spécifique à mon traitement... c'est vraiment gentil :D :rolleyes:

 

Je teste dans l'après-midi et je reviendrai un peu plus tard valider (sûrement) la réponse.

 

Bon après-midi en attendant..

 

Hyppo

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

J'espère avoir répondu à tes attentes..

 

Hyppolight

 

Oui ! merci c'est toujours intéressant de voir ce que l'on peut développer surtout quand comme moi on ne touche pas au code !

 

Bon courage !

Autocad Map 3D 2024 - Covadis version 18.1 - Windows Onze

"Si j'avais du lard je vous ferais une omelette au lard mais j'ai pas d'oeuf..."
Coluche

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Pour modifier la vue dans une fenêtre, il faut jouer sur les propriétés ViewDirection et TwistAngle de l'objet viewport.

Ceci peut se faire indépendamment du SCU (autrement dit, on n'est pas obligé de modifier le SCU dans la fenêtre pour en changer la vue). Comme les données sont stockées dans un SCU nommé on pourrait simplement récupérer ces données.

 

 

 

Rebonjour,

 

J'ai adapté ton code à mon exemple et ça marche parfaitement bien.

 

Juste un petite remarque: j'ai modifié le point d'origine (Point3D.origin) dans la propriété TwistAnle par itbr.Origin pour que mon point d'origine soit coincident avec le point de base de mon scu...

 

Encore merci... et à bientôt ;) :P

 

Ci-dessous mon code mis à jour (en VB.NET pour ceux qui voudront)

 

 


   <DllImport("accore.dll", CallingConvention:=CallingConvention.Cdecl, _
EntryPoint:="?acedSetCurrentVPort@@YA?AW4ErrorStatus@Acad@@PEBVAcDbViewport@@@Z")> _
   Public Shared Function acedSetCurrentVPort(ByVal AcDbVport As IntPtr) As IntPtr
   End Function

'Mise en forme de la fenêtre : gestion SCU / echelle
   Public Sub MISE_EN_FORME_FENETRE_FUN(TRONCON As String, SEGMENT As String, ALT As String, NomLayout As String, GRD As clGRD)

       Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
       Dim db As Database = doc.Database
       Dim ed As Editor = doc.Editor
       Dim layId As ObjectId
       Dim lo As Layout
       Dim loName As String

       Dim tilemode As Short = CShort(AcadAp.GetSystemVariable("TILEMODE"))
       Dim cvPort As Short = CShort(AcadAp.GetSystemVariable("CVPORT"))

       Using doclok As DocumentLock = doc.LockDocument()

           Using tr As Transaction = doc.Database.TransactionManager.StartTransaction

               Try

                   Dim laydic As DBDictionary = DirectCast(tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead, False), DBDictionary)

                   For Each dentry As DictionaryEntry In laydic

                       layId = DirectCast(dentry.Value, ObjectId)
                       lo = DirectCast(tr.GetObject(layId, OpenMode.ForRead), Layout)
                       loName = lo.LayoutName

                       If loName = NomLayout Then

                           Dim Coll As ObjectIdCollection = CollectVieports(lo, doc)

                           'Une seule fenête par présentation à ce moment là
                           Dim VP_ID As ObjectId = Coll(0)

                           Dim r As BlockTableRecord = TryCast(tr.GetObject(lo.BlockTableRecordId, OpenMode.ForRead), BlockTableRecord)

                           For Each obj As ObjectId In r

                               Dim dbobj As DBObject = tr.GetObject(obj, OpenMode.ForRead)
                               Dim vp As DatabaseServices.Viewport = TryCast(dbobj, DatabaseServices.Viewport)

                               If vp IsNot Nothing Then

                                   If vp.ObjectId = VP_ID Then

                                       vp.UpgradeOpen()

                                       vp.On = True
                                       vp.Visible = True

                                       ' Set the new viewport current via an imported ObjectARX function
                                       acedSetCurrentVPort(vp.UnmanagedObject)

                                       ' Activate model space in the viewport
                                       ed.SwitchToModelSpace()

                                       'Définition du SCU associé à la planche
                                       Dim SCU_NAME As String = "SCU_T" & TRONCON & "_S" & SEGMENT & "_A" & ALT

                                       Dim utb As UcsTable = CType(tr.GetObject(db.UcsTableId, OpenMode.ForRead), UcsTable)

                                       Dim zAxis As Vector3d


                                       If utb.Has(SCU_NAME) Then

                                           Dim itbr As UcsTableRecord = CType(tr.GetObject(utb.Item(SCU_NAME), OpenMode.ForRead), UcsTableRecord)

                                           Dim ucsMat As Matrix3d = Matrix3d.AlignCoordinateSystem( _
                                           Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, _
                                           itbr.Origin, itbr.XAxis, itbr.YAxis, itbr.XAxis.CrossProduct(itbr.YAxis))

                                           ed.CurrentUserCoordinateSystem = ucsMat

                                           ed.SwitchToPaperSpace()

                                           zAxis = itbr.XAxis.CrossProduct(itbr.YAxis)
                                           vp.ViewDirection = zAxis
                                           vp.TwistAngle = -itbr.XAxis.AngleOnPlane(New Plane(itbr.Origin, zAxis))

                                       End If


                                       Exit For

                                   End If

                               End If

                           Next

                           Exit For

                       Else

                       End If
                   Next

               Catch ex As System.Exception
                   MsgBox(ex.ToString)
                   ed.WriteMessage(vbLf & ex.Message & vbLf & ex.StackTrace)
               End Try

               tr.Commit()
               tr.Dispose()
               ed.Regen()

           End Using 'tr


       End Using 'DocumentLock

   End Sub

   'Listing des fenêtres dans une présentation définie
   Function CollectVieports(ByRef lo As Layout, ByRef doc As Document) As ObjectIdCollection
       Dim db As Database = doc.Database
       Dim Btr As BlockTableRecord
       Dim vp As DatabaseServices.Viewport
       Dim oidcol As ObjectIdCollection = New ObjectIdCollection()
       Dim notpvp As Boolean 'don't include the general layout vp
       Using trans As Transaction = db.TransactionManager.StartTransaction()
           Btr = DirectCast(trans.GetObject(lo.BlockTableRecordId, OpenMode.ForRead), BlockTableRecord)
           For Each oid As ObjectId In Btr
               vp = TryCast(trans.GetObject(oid, OpenMode.ForRead), DatabaseServices.Viewport)
               If Not vp Is Nothing Then
                   If notpvp Then oidcol.Add(oid)
                   notpvp = True
               End If

           Next
       End Using
       Return oidcol
   End Function


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é