| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Objekte zurückskalieren (1240 mal gelesen)
|
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 02. Jun. 2010 07:22 <-- editieren / zitieren --> Unities abgeben:
Hallo! Ich habe folgendes Problem. Ich habe einen Rahmen und Schriftkopf(mit Attributen) im Layout und diese sind eventuell Skaliert (*2,*3,..) oder auch nicht. Wenn ich jetzt die Blockreferenzen durchgehe und den Faktor auf 1 stelle bei X,Y,Z ist mein Schriftkopf (rechts unten) nicht mehr an der richtigen Position. D.h der gehört auch noch nach inks geschoben. Da wäre schon die erste Frage, werden die Objekte, wenn die Skalierung geändert wird, immer nach rechts oben verlängert, oder kann dass auch andersrum gehen? Bei mir handelt es sich nur um normale Blockreferenzen. Nächste Frage, wenn ich bei einem Block die Saklierung änder, werden die Attribute im Block nicht auch automatisch zurückskaliert? Hier der Code wo ich die Elemente ins Layout kopiere und auf 0,0 verschiebe + die Saklierung auf 1 änder, hier ist das verschieben des Schriftkopfes noch nicht dabei. Ich weiß auch noch nicht wie ich das am besten berechnen soll... Code:
Dim CopyColl As DatabaseServices.DBObjectCollection = New DatabaseServices.DBObjectCollection Dim CopyExtents As DatabaseServices.Extents3d For Each ObjID As DatabaseServices.ObjectId In SelSet.Value.GetObjectIds 'erstmal Element kopieren Dim DBObj As DatabaseServices.Entity = TryCast(TrAct.GetObject(ObjID, DatabaseServices.OpenMode.ForRead, True, True), DatabaseServices.Entity) If DBObj IsNot Nothing Then Dim CloneObj As DatabaseServices.Entity = CType(DBObj.Clone, DatabaseServices.Entity) LayoutBlDef.AppendEntity(CloneObj) TrAct.AddNewlyCreatedDBObject(CloneObj, True) CopyColl.Add(CloneObj) If CopyColl.Count = 1 Then CopyExtents = CloneObj.GeometricExtents Else CopyExtents.AddPoint(CloneObj.GeometricExtents.MinPoint) CopyExtents.AddPoint(CloneObj.GeometricExtents.MaxPoint) End If End If Next 'Auf 0,0 schieben, Skalierung auf 1 stellen Dim blockref As BlockReference Dim MoveMatrix As Geometry.Matrix3d = Geometry.Matrix3d.Displacement(New Geometry.Vector3d(-CopyExtents.MinPoint.X, -CopyExtents.MinPoint.Y, -CopyExtents.MinPoint.Z)) For Each DBObj As DatabaseServices.Entity In CopyColl DBObj.TransformBy(MoveMatrix) blockref = CType(DBObj.ObjectId.GetObject(OpenMode.ForWrite, True, True), BlockReference) blockref.ScaleFactors = New Geometry.Scale3d(1, 1, 1) Next
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 02. Jun. 2010 07:47 <-- editieren / zitieren -->
Hi, >> werden die Objekte, wenn die Skalierung geändert wird, immer nach rechts oben verlängert Nein, bei Änderung der Blockreferenz-Skalierung werden die Elemente immer in bezug auf den Blockbasispunkt gerechnet. Ist der Blockbasispunkt links-unten, dann wird mit größerer Skalierung nach rechts-oben erweitert. Ist der Blockbasispunkt rechts-unten, dann wird eben nach links-oben erweitert/verkleinert (bei kleinerem Skalierfaktor). Für einen Schriftkopf, der ja im Layout zumeist rechts-unten angelegt ist, wäre ein Blockbasispunkt auch rechts-unten (schon wegen des Einfügens) vorteilhaft. >> wenn ich bei einem Block die Saklierung änder, werden die Attribute im Block nicht auch automatisch zurückskaliert?
Nein, Du musst die AttributeCollection der Blockreferenz mit durchgehen und skalieren. - alfred -
------------------ www.hollaus.at |
Brischke Moderator CAD on demand GmbH
Beiträge: 4171 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools
|
erstellt am: 02. Jun. 2010 07:50 <-- editieren / zitieren --> Unities abgeben: Nur für veydan
Hallo veydan, die Blöcke werden immer zur Basis ihres Einfügepunktes (Eigenschaft Position) skaliert. zu deinem Schriftkopf hätte ich die folgende Idee: 1) BoundingBox abfragen (Eigenschafte: Extents) 2) aus den Extents die Koordinate unten rechts berechnen -> COOold 3) Block skalieren 4) Boundingbox abfragen 5) aus diesen Extents wiederum die Koordinate unten rechts ermitteln -> COOnew 6) Vector von COOnew nach COOold berechnen ->MoveVector 7) Position Eigenschaft + MoveVector fertig. Die Attribute eines Blockes musst du ebenfalls alle skalieren, und deren Position ebenfalls entsprechend des Skalierfaktors neu berechnen - das ist normal, da kommst nicht drumherum. Einziger Ausweg wäre, dass du hinterher ein Attsync über alle Blöcke schickst. Grüße Holger
------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 02. Jun. 2010 09:29 <-- editieren / zitieren --> Unities abgeben:
Danke für die Hinweise. @Brischke Deine Berechnung kann nicht funktionieren, denn der Schriftkopf z.b bleibt ja auf der stelle wer wird ja von links nach rechts verkleinert, weil der Einfügepunkt rechts unten ist, dass heißt er bleibt auch auf der Position wie alfred dass auch gesagt hat. Ich habe die Berechnung so gemacht für X: Der Vector für die Verschiebung lautet bei mir:
Code:
MoveVector = New Geometry.Vector3d(-(width * (scl - 1)), 0, 0)
width ist die Breite des Rahmen mit Skalierfaktor 1, scl ist der Skalierfaktor den der Rahmen ursprünglich hatte(2,3,4,...) dass funktioniert soweit so gut, bis auf die Rahmendicke.Diese weiß ich nicht wie ich die mit einbeziehen soll. Standardmäßig besteht der Rahmen ja aus 2 Rechtecken, wobei das eine etwas länger und höher ist. diese Breite fehlt mir noch für die korrekte Verschiebungedit: Ich sollte noch dazusagen, dass der Rahmen mit Einfügepunkt links unten, bereits auf 0,0,0 liegt. d.h dieser muss nur zurückskaliert werden und nicht verschoben. mfg
[Diese Nachricht wurde von veydan am 02. Jun. 2010 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 04. Jun. 2010 16:05 <-- editieren / zitieren --> Unities abgeben:
so das Problem mit der Skalierung ist gelöst, jetzt hätte ich noch eine frage zum Verschieben der Schriftkopf Attributen. Gibt es da eine einfache und kurze Möglichkeit den Schriftkopf(den hab ich schon) und alle enthaltenen Elemente der Blockreferenz mitzuverschieben? mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 04. Jun. 2010 20:29 <-- editieren / zitieren -->
Hi, gleiche Vorgehensweise: a) Du machst eine Transformationsmatrix für die Verschiebung b) Du verschiebst mit dieser Matrix die BlockReference c) Du scannst durch die AttributeCollection und für jede AttRef d) Verschieben der AttRef mittels gleicher Transformation Code: Dim tOldInsPnt As Geometry.Point3d = BlRef.Position Dim tMoveVec As Geometry.Vector3d = New Geometry.Vector3d(NewInsPnt.X - tOldInsPnt.X, NewInsPnt.Y - tOldInsPnt.Y, NewInsPnt.Z - tOldInsPnt.Z) BlRef.Position = NewInsPnt 'das ist der neue Punkt, und damit wird die BlockRef geschoben'und jetzt noch nach attributen umsehen If (BlRef.AttributeCollection IsNot Nothing) AndAlso (BlRef.AttributeCollection.Count > 0) Then Dim tMoveMat As Geometry.Matrix3d = Geometry.Matrix3d.Displacement(tMoveVec) For Each tObjID As ObjectId In BlRef.AttributeCollection CType(ISHAcTools.getObjectByObjectID(TrAct, tObjID, OpenMode.ForWrite), Entity).TransformBy(tMoveMat) Next End If
- alfred -
------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 07. Jun. 2010 06:55 <-- editieren / zitieren --> Unities abgeben:
hallo, danke alfred! die Verschiebung klappt, aber in der Form hatte ich es auch schon, nur dachte ich ich mache etwas falsch, da bei dir auch die Skalierung?? nicht geändert wird. ich stelle meine Blockref auf: Code: blockref.ScaleFactors = New Geometry.Scale3d(1, 1, 1)
wenn ich die Attribute dann durchlaufe und auch verschiebe, sieht es so aus als ob die noch im alten Scale sind, der SK aber nicht mehr. Eine Attributereference hat aber keine Scale Eigenschaft. Wo muss man da den Hebel ansetzen?mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 07. Jun. 2010 07:28 <-- editieren / zitieren -->
Hi, >> da bei dir auch die Skalierung?? nicht geändert wird Nein, die Skalierung hab ich nicht eingebaut, denn in Deiner letzte Frage stand: >> ...noch eine frage zum Verschieben der Schriftkopf Attributen Nun in gleicher Art und Weise wie oben, nimm eine TranformationMatrix. Code: Dim tOldScale As Double = BlRef.ScaleFactors.X Dim tScale As Geometry.Scale3d = New Geometry.Scale3d(NewScaleFactor, NewScaleFactor, NewScaleFactor) BlRef.ScaleFactors = tScale'und jetzt noch nach attributen umsehen If (BlRef.AttributeCollection IsNot Nothing) AndAlso (BlRef.AttributeCollection.Count > 0) Then Dim tScaleMat As Geometry.Matrix3d = Geometry.Matrix3d.Scaling(NewScaleFactor / tOldScale, BlRef.Position) For Each tObjID As ObjectId In BlRef.AttributeCollection CType(ISHAcTools.getObjectByObjectID(TrAct, tObjID, OpenMode.ForWrite), Entity).TransformBy(tScaleMat) Next End If End If
Vorsicht ist hier aber geboten, wenn die Skalierung nicht einheitlich ist (also NCIHT: XScale=YScale=ZScale), dann könnte es Brösel geben. - alfred -
------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 07. Jun. 2010 08:27 <-- editieren / zitieren --> Unities abgeben:
|
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|