Hyppolight Posté(e) le 23 mars 2017 Posté(e) le 23 mars 2017 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
DaWeeD_Gab Posté(e) le 23 mars 2017 Posté(e) le 23 mars 2017 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 2025 - Covadis version 18.3b - Windows Onze "Si j'avais du lard je vous ferais une omelette au lard mais j'ai pas d'oeuf..." Coluche
Hyppolight Posté(e) le 23 mars 2017 Auteur Posté(e) le 23 mars 2017 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
(gile) Posté(e) le 23 mars 2017 Posté(e) le 23 mars 2017 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(); } } 1 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Hyppolight Posté(e) le 23 mars 2017 Auteur Posté(e) le 23 mars 2017 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 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
DaWeeD_Gab Posté(e) le 23 mars 2017 Posté(e) le 23 mars 2017 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 2025 - Covadis version 18.3b - Windows Onze "Si j'avais du lard je vous ferais une omelette au lard mais j'ai pas d'oeuf..." Coluche
Hyppolight Posté(e) le 23 mars 2017 Auteur Posté(e) le 23 mars 2017 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
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