| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| PNY bietet das umfangreichste Ökosystem von B2B als auch B2C-Lösungen für IT-Akteure auf dem Markt, eine Pressemitteilung
|
Autor
|
Thema: Isolate 3DSOLID aus Block (1581 / mal gelesen)
|
Dirk.B Mitglied Tischler / Leiter Arbeitsvorbereitung
Beiträge: 534 Registriert: 25.11.2003 AutoCAD 2017/2018 CAD+T HP ZBook 15 G4, 64-bit, WIN 10 Pro
|
erstellt am: 22. Jan. 2019 09:29 <-- editieren / zitieren --> Unities abgeben:
Hallo Zusammen! Es ist schon eine Weile her, dass ich mich mit Lisp beschäftigt habe. Wir arbeiten mit verschachtelten Blöcken, soll bedeuten, in einem Block gibt es immer ein 3DSOLID auf dem Layer AZC_MCSYMBOL_LB. Um diese 3DSOLID's als *.dwf Datei speichern zu können, möchte ich mir diese gern aus den Blöcken heraus isolieren um sie dann exportieren zu können. Leider bekomme ich es nicht hin und hoffe auf eure Unterstützung. Folgendes hatte ich so oder ähnlich bereits probiert:
Code:
(defun c:cadexdwf ( / i ssa ssb) (vl-load-com) (setq i 1) (setq sse (ssget "X" (list (cons 0 "INSERT")))) (while (setq ssb (ssget "_x" '((0 . "3DSOLID")(8 . "AZC_MCSYMBOL_LB"))))) (if ssb(command "_IsolateObjects" sse "")) ) (princ)
Ich komme einfach nicht an die verschachtelten 3DSOLID's!? Vielen Dank schon einmal. ------------------ Gruß Dirk Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 22. Jan. 2019 09:37 <-- editieren / zitieren --> Unities abgeben: Nur für Dirk.B
Hallo Dirk, du hast 2 Gedankenfehler: 1) Das gesuchte Solid ist nicht Bestandteil der Blockreferenz (INSERT) - dieses ist Bestandteil der Blockdefinition 2) Ich habe keine Ahnung, ob das Isolieren überhaupt auf verschachtelte Elemente angewandt werden kann. Ich bin mir aber sicher, wenn du den Export machst, dass dann die Blockreferenz exportiert wird. Lösung: Explodiere alle INSERTs (Blockreferenzen), ggf. rekursiv, dann kannst du auch direkt die Solids in den Auswahlsatz einsammeln. Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Dirk.B Mitglied Tischler / Leiter Arbeitsvorbereitung
Beiträge: 534 Registriert: 25.11.2003 AutoCAD 2017/2018 CAD+T HP ZBook 15 G4, 64-bit, WIN 10 Pro
|
erstellt am: 22. Jan. 2019 09:59 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger! Danke für dein Feedback. Da an diesen Blöcken eine Menge Informationen (XDATA) hängen, da diese Bestandteil einer Aufsatzsoftware auf AutoCAD sind, würde ich die Blöcke nur ungern sprengen. Müsste da aber auch beim einsammeln der Solids passen, da ich nicht wüste, wie ich das per Lisp hinbekomme. In AutoCAD gibt es ja den Befehl NKOPIE mit dem ich ein Solid aus einen Block kopieren kann. Könnte man das irgendwie mit Lisp umsetzen? ------------------ Gruß Dirk Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 22. Jan. 2019 10:09 <-- editieren / zitieren --> Unities abgeben: Nur für Dirk.B
... warum unbedingt Lisp? Wenn ich's richtig sehe, bist doch auch auf .Net-Seite unterwegs - da ist das aus meiner Sicht ein Kinderspiel, die Objekte aus den Blockreferenzen rauszuholen und dann zu exportieren. Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Dirk.B Mitglied Tischler / Leiter Arbeitsvorbereitung
Beiträge: 534 Registriert: 25.11.2003 AutoCAD 2017/2018 CAD+T HP ZBook 15 G4, 64-bit, WIN 10 Pro
|
erstellt am: 22. Jan. 2019 10:31 <-- editieren / zitieren --> Unities abgeben:
|
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 22. Jan. 2019 11:10 <-- editieren / zitieren --> Unities abgeben: Nur für Dirk.B
ff c#.Net ungetestet! Code:
public static void RunTool() { string _resultDwgName = @"c:\Temp\result.dwg"; string _layername = "HIER_LAYERNAMEN_DER SOLIDS EINTRAGEN"; Database _db = HostApplicationServices.WorkingDatabase; // Liste der Ids der kopierten Solids ObjectIdCollection _SolidIdsInModelSpace = new ObjectIdCollection(); using (Transaction _tr = _db.TransactionManager.StartTransaction()) { using (BlockTable _bt = (BlockTable)_tr.GetObject(_db.BlockTableId, OpenMode.ForRead)) { // Alle Blöcke durchlaufen foreach (ObjectId _oid in _bt) { using (BlockTableRecord _btr = (BlockTableRecord)_tr.GetObject(_oid, OpenMode.ForRead)) { // alle Blockreferenzen ermitteln ObjectIdCollection _refIds = _btr.GetBlockReferenceIds(true, true); foreach (ObjectId _eid in _btr) { // Alle Elemente eines Blocks durchlaufen Entity _ent = (Entity)_tr.GetObject(_eid, OpenMode.ForWrite); { if (_ent.Layer == _layername && typeof(Solid3d).IsAssignableFrom(_ent.GetType())) { // Wenn Element = Solid3d auf Layer foreach (ObjectId _rId in _refIds) { // ... dann alle Blockreferenzen des Blocks durchlaufen using (BlockReference _br = (BlockReference)_tr.GetObject(_rId, OpenMode.ForRead)) { // Solidobjekt kopieren using (Solid3d _newSolid = (Solid3d)_ent.Clone()) { // Solidobject aus der Blockdefinition in den Bereich der aktuellen Blockreferenz transformieren _newSolid.TransformBy(_br.BlockTransform); using (BlockTableRecord _ms = (BlockTableRecord)_tr.GetObject(_br.OwnerId, OpenMode.ForWrite)) { // Solid in den Bereich der aktuellen Blockreferenz einfügen & ObjektId der Liste der neuen Solids hinzufügen _SolidIdsInModelSpace.Add(_ms.AppendEntity(_ent)); _tr.AddNewlyCreatedDBObject(_ent, true); } } } } } } } } } } // Solids exportieren. _db.Wblock(_SolidIdsInModelSpace, Point3d.Origin).SaveAs(_resultDwgName, DwgVersion.Current); // Einkommentieren, wenn das Ergebnis in der aktuellen Zeichnung sichtbar sein soll //_tr.Commit(); } }
Vielleicht hilfts? Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Dirk.B Mitglied Tischler / Leiter Arbeitsvorbereitung
Beiträge: 534 Registriert: 25.11.2003 AutoCAD 2017/2018 CAD+T HP ZBook 15 G4, 64-bit, WIN 10 Pro
|
erstellt am: 28. Jan. 2019 10:37 <-- editieren / zitieren --> Unities abgeben:
|
Dirk.B Mitglied Tischler / Leiter Arbeitsvorbereitung
Beiträge: 534 Registriert: 25.11.2003 AutoCAD 2017/2018 CAD+T HP ZBook 15 G4, 64-bit, WIN 10 Pro
|
erstellt am: 01. Feb. 2019 16:31 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger! Sicherlich sind wir hier bei Lisp, aber ...! Ich habe das einmal versucht umzusetzen. Vorgefiltert werden sollen: - Blöcke "INSERT" - BlockName Dann durchlaufen und die Solids als WBlock speicheren. Es wird auch eine "c:\Temp\result.dwg" erzeugt aber ohne Inhalt. Kannst du dir das bitte noch einmal anschauen und mir dabei helfen. Code:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim _doc As Document = DocumentManager.MdiActiveDocument Dim _db As Database = _doc.Database Dim _ed As Editor = _doc.Editor Dim _resultDwgName As String = "c:\Temp\result.dwg" Dim _layername As String = "AZC_MCSYMBOL_LB" Dim _SolidIdsInModelSpace As ObjectIdCollection = New ObjectIdCollection() Using _tr As Transaction = _db.TransactionManager.StartTransaction Try Dim MyFiList(1) As TypedValue MyFiList.SetValue(New TypedValue(DxfCode.Start, "INSERT"), 0) MyFiList.SetValue(New TypedValue(DxfCode.BlockName, "GEN*"), 1) ' MyFiList.SetValue(New TypedValue(DxfCode.LayerName, "AZC_*"), 2) ',AZC_MODEL*"), 2) Dim _mf As New SelectionFilter(MyFiList) Dim _res As PromptSelectionResult = _ed.SelectAll(_mf) If _res.Status <> PromptStatus.OK Then Return End If Dim selSet As SelectionSet = _res.Value Dim idArray As ObjectId() = selSet.GetObjectIds() For Each blkId As ObjectId In idArray Dim blkRef As BlockReference = DirectCast(_tr.GetObject(blkId, OpenMode.ForRead), BlockReference) Dim _btr As BlockTableRecord = DirectCast(_tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead), BlockTableRecord) Dim attCol As AttributeCollection = blkRef.AttributeCollection Dim _refIds As ObjectIdCollection = _btr.GetBlockReferenceIds(True, True) For Each _eid As ObjectId In _btr Dim _ent As Entity = CType(_tr.GetObject(_eid, OpenMode.ForWrite), Entity) If True Then If _ent.Layer = _layername AndAlso GetType(Solid3d).IsAssignableFrom(_ent.[GetType]()) Then For Each _rId As ObjectId In _refIds Dim _br As BlockReference = CType(_tr.GetObject(_rId, OpenMode.ForRead), BlockReference) Dim _newSolid As Solid3d = CType(_ent.Clone(), Solid3d) _newSolid.TransformBy(_br.BlockTransform) _ed.WriteMessage("CAD+T 3DSolid =" & _newSolid.Layer & vbCrLf) Dim _ms As BlockTableRecord = CType(_tr.GetObject(_br.OwnerId, OpenMode.ForWrite), BlockTableRecord) _SolidIdsInModelSpace.Add(_ms.AppendEntity(_ent)) _tr.AddNewlyCreatedDBObject(_ent, True) _tr.Commit() Next End If End If Next Next _tr.Commit() _db.Wblock(_SolidIdsInModelSpace, Point3d.Origin).SaveAs(_resultDwgName, DwgVersion.Current) '---Fehler im Prozessdurchlauf abfangen-----!! Catch ex As Autodesk.AutoCAD.Runtime.Exception '--Fehler im Prozessdurchlauf abfangen--!! MsgBox("Fehlermeldung", MsgBoxStyle.Information, ex.Message) End Try End Using End Sub
Mit deinem Code meckert AutoCAD immer Layer an, die gesperrt sind. Vielen Dank.
------------------ Gruß Dirk Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 01. Feb. 2019 18:25 <-- editieren / zitieren --> Unities abgeben: Nur für Dirk.B
Hallo Dirk, ich habe nun meinen Code getestet und einen Fehler festgestellt (der hätte bei dir aber auch kommen müssen??). In den folgenden 2 Codezeilen muss _ent durch _newSolid ersetzt werden - danach hat es bei mir sauber funktioniert. Wenn ich das in deinem VB-Code richtig sehe, ist das auch bei dir so, also noch zu ändern!
Code:
// Solid in den Bereich der aktuellen Blockreferenz einfügen & ObjektId der Liste der neuen Solids hinzufügen _SolidIdsInModelSpace.Add(_ms.AppendEntity(_newSolid)); _tr.AddNewlyCreatedDBObject(_newSolid, true);
Grundsätzlich funktioniert der Code nicht, wenn du bei mehrfach verschachtelten Blöcken die Solids nicht aus der 1. Blockebene extrahieren willst. Dafür müsste der Code erweitert werden - sollte aber bei der Prinzipskizze, mehr sollte mein Bsp-Code nicht sein, wohl aber machbar sein. Was mich an deinem Code wundert ist, dass du nur eine Transaction startest aber mehrere Commit()-Aufrufe hast? Es genügt ein Commit ganz am Ende, wenn du die innerhalb der Transaction vollzogenen Änderungen auch tatsächlich in die Zeichnungsdatenbank übernehmen möchtest - dabei ist es egal, in welchem Codezweig oder darin aufgerufenen SubFunction du Änderungen vornimmst. Ich werde mir zum Testen deines Codes kein VB-Project anlegen und zum Testen auch nicht deinen Code nach C# übersetzen. (Damit habe ich einfach Null-Erfahrung :-( )
Bei Fragen ... Grüße! Holger
------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Dirk.B Mitglied Tischler / Leiter Arbeitsvorbereitung
Beiträge: 534 Registriert: 25.11.2003 AutoCAD 2017/2018 CAD+T HP ZBook 15 G4, 64-bit, WIN 10 Pro
|
erstellt am: 02. Feb. 2019 14:10 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger! Habe mir unter C# ein kleines Programm angelegt, habe aber mit C# überhaupt keine Erfahrung. Starte ich dein Programm hängt es bei Objekten, die auf einem gesperrten Layer liegen (Zeichnungsrahmen als Block, etc.). Kann man diese in deiner Abfrage noch umgehen/überspringen?
------------------ Gruß Dirk Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 02. Feb. 2019 16:28 <-- editieren / zitieren --> Unities abgeben: Nur für Dirk.B
... geht! Schau mal beim _tr.GetObject(...) da gibt es eine Überlastung [OpenOnLockedLayer] oder so ähnlich. Wenn das auf true steht, ist’s egal ob Layer gesperrt sind. (Ich bin nicht am Rechner, sonst hätte ich das korrekt nennen können. Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 03. Feb. 2019 08:15 <-- editieren / zitieren --> Unities abgeben: Nur für Dirk.B
Hallo Dirk, anbei findest du nun die vollständige Solution. In diese habe ich auch das Handling tiefer in Blöcken verschachtelter 3d-Solids eingebaut. Zum gleich testen sind anbei auch die Programmdateien für AutoCAD 2011 - 2019.(da ist Voraussetzung, dass die Solids auf Layer "0" liegen und das Ergebnis wird nach "c:\Temp\result.dwg" gespeichert) Das ist alles in c#.Net gemacht, ich hoffe, du kommst klar. Grüße! Holger
------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Dirk.B Mitglied Tischler / Leiter Arbeitsvorbereitung
Beiträge: 534 Registriert: 25.11.2003 AutoCAD 2017/2018 CAD+T HP ZBook 15 G4, 64-bit, WIN 10 Pro
|
erstellt am: 07. Feb. 2019 09:24 <-- editieren / zitieren --> Unities abgeben:
|