Hot News:

Mit Unterstützung durch:

  Foren auf CAD.de (alle Foren)
  AutoCAD ObjectARX und .NET
  Nur die Größen gefüllter Flächen anzeigen

Antwort erstellen  Neues Thema erstellen
CAD.de Login | Logout | Profil | Profil bearbeiten | Registrieren | Voreinstellungen | Hilfe | Suchen

Anzeige:

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen nächster neuer Beitrag | nächster älterer Beitrag
  
Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte
Autor Thema:  Nur die Größen gefüllter Flächen anzeigen (2400 mal gelesen)
mOfl
Mitglied



Sehen Sie sich das Profil von mOfl an!   Senden Sie eine Private Message an mOfl  Schreiben Sie einen Gästebucheintrag für mOfl

Beiträge: 22
Registriert: 25.09.2010

erstellt am: 05. Nov. 2010 17:01    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo,

wieder einmal brauche ich eure Hilfe. Ich habe mehrere Polylinien auf einem Layer, die eine Fläche begrenzen. Die Fläche soll mittels Schraffur ausgefüllt werden, d.h. es sollen auch alle Inseln berücksichtigt werden, die durch die Polylinien entstehen können. Es ist auch möglich, dass sich keine der Polylinien überschneiden. Das funktioniert ohne Probleme:

Code:
TypedValue[] tvs = new TypedValue[1];
tvs[0] = new TypedValue((int) DxfCode.LayerName, layer);

SelectionFilter sf = new SelectionFilter(tvs);
PromptSelectionResult psr = AcadEditor.SelectAll(sf);

Hatch hat = new Hatch();
hat.SetDatabaseDefaults();
hat.Layer = layer;
hat.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");

ObjectId hatId = btr.AppendEntity(hat);
tr.AddNewlyCreatedDBObject(hat, true);

ObjectIdCollection ids = new ObjectIdCollection();

hat.Associative = true;

foreach (ObjectId id in psr.Value.GetObjectIds()) {
Entity ent = (Entity) tr.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite);
ent.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(0, 0, 0);

ids.Add(id);

hat.AppendLoop(HatchLoopTypes.Default, ids);

ids.Clear();
}

hat.EvaluateHatch(true);


Jetzt will ich die Größen dieser Flächen mithilfe von Fields anzeigen. Ich kann zwei Varianten sehr einfach realisieren, die Fläche der gesamten Hatch ausgeben oder die Fläche jeder Polylinie. Ersteres ist leider zu ungenau, weil sich die Polylinien nicht zwangsläufig überschneiden, d.h. völlig unabhängige Flächen hätten nur eine aufsummierte Flächenangabe. Zweites führt zu dem Problem, dass alle Flächengrößen angezeigt werden, auch die der Inseln (also der Polygone, die als innere Begrenzung der Hatch dienen). Außerdem werden hierbei die Inseln ja nicht subtrahiert, sodass die Inselfläche von der Fläche des Außenpolygons noch abgezogen werden müsste.

Der Code für die Beschriftung aller Flächen:

Code:
TypedValue[] tvs = new TypedValue[1];
tvs[0] = new TypedValue((int) DxfCode.LayerName, entityLayer);

SelectionFilter sf = new SelectionFilter(tvs);
PromptSelectionResult psr = AcadEditor.SelectAll(sf);

foreach (ObjectId id in psr.Value.GetObjectIds()) {
Entity ent = (Entity) tr.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite);
double[] inpunkt = getInpunkt(id);

if (inpunkt != null) {
MText text = new MText();

TextStyleTable textStyleTbl = (TextStyleTable) AcadDB.TextStyleTableId.GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
TextStyleTableRecord txtrcd = (TextStyleTableRecord) textStyleTbl["ARIAL"].GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);

text.TextStyleId = txtrcd.ObjectId;
text.Layer = textLayer;
text.TextHeight = 1.25;
text.Attachment = AttachmentPoint.MiddleCenter;
text.Location = new Point3d(inpunkt[0], (double) inpunkt[1], 0.0);
text.SetContentsRtf("%<\\AcExpr abs(%<\\AcObjProp Object(%<\\_ObjId " + id.ToString().Substring(1, id.ToString().Length - 2) + ">%).Area>%) \\f \"%lu2%pr2%ds44\">%");

AcadEditor.Regen();

ObjectId textId = btr.AppendEntity(text);
tr.AddNewlyCreatedDBObject(text, true);
}
}


Und ein Bild des Resultats mit beschrifteter Insel (die orangene Fläche ist die neu angelegte):

Meine Frage ist jetzt, wie ich die Funktion(en) so umstellen kann, dass nur die Flächen der wirklich gefüllten Flächen angezeigt werden, aber für jede dieser Flächen einzeln und nicht die Fläche der kompletten Hatch. Kann man ein Hatch-Objekt eventuell in einzelne Komponenten zerlegen? Das wäre vermutlich ein einfacher Weg, wenn es so eine Funktion gäbe.

Gruß
mOfl

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP


Ex-Mitglied

erstellt am: 06. Nov. 2010 10:37    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat

Hi,

solange Du ein (gesamtes) Hatchobjekt erstellst, wird in der Beschriftung immer die gesamte Fläche (aller Teilschraffuren) angezeigt werden. Willst Du diese trennen, hast Du nur die Chance mit eigenen geometrischen Rechnungen, um die Grenzen der Teilflächen herauszufinden und damit Einzelschraffuren zu erzeugen.
Vorgefertige Funktionen in der API wären mir dafür nicht bekannt.

Wenn Du Deinen gesamten Workflow umbauen kannst, dann könntest Du den Befehl bzw. die API für GPOLY (_BPOLY) nutzen. Punkt in einer Fläche zeigen, daraus entsteht dann eine Region oder Polylinie und damit der Flächenwert für diese Einzelfläche. Dieses bedingt aber dann mehrfaches Klicken des Users (oder Ermittlung des Punktes durch das Programm) je Fläche.

- alfred -

------------------
www.hollaus.at

mOfl
Mitglied



Sehen Sie sich das Profil von mOfl an!   Senden Sie eine Private Message an mOfl  Schreiben Sie einen Gästebucheintrag für mOfl

Beiträge: 22
Registriert: 25.09.2010

erstellt am: 08. Nov. 2010 21:42    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Vielen Dank für deine Antwort! Es funktioniert nun. Ich habe jetzt eine Baumstruktur erzeugt, die speichert, welche Polylinien innerhalb von anderen Polylinien liegen. Die Überprüfung "Punkt innerhalb Polylinie" hat mir Schwierigkeiten bereitet.

Mein erster Ansatz:

Code:
private bool pointInsidePolyline(Point3d point, Autodesk.AutoCAD.DatabaseServices.Polyline polyline) {
try {
MPolygon mpolygon = new MPolygon();
mpolygon.AppendLoopFromBoundary(polyline, false, 0.0001);
AcadEditor.WriteMessage("hugo3\n");

return (mpolygon.IsPointInsideMPolygon(point, 0.0001).Count > 0);
}
catch (System.Exception ex) {
AcadEditor.WriteMessage("exception in pointinside: " + ex.Message + "\n");
return false;
}
}


Problem: Die Ausgabe ist immer false, da new MPolygon() eine Exception mit der Message "acmpolygonobj18d.dbx" wirft. Google zeigt nur einen Treffer dafür: http://forums.autodesk.com/t5/AutoCAD-Map-3D-Developer/Map-2010-VB-NET-2008-Create-Mpolygon-error/td-p/2502725

Anscheinend ein Bug, leider bin ich kein ADN-Mitglied. Schade, denn das wäre eine sehr einfache Lösung des Problems gewesen. Deshalb habe ich jetzt den üblichen geometrischen Ansatz implementiert, allerdings ohne Behandlung des Falls, dass der Schnittpunkt genau ein Eckpunkt der Polylinie ist.

Code:
private bool pointInsidePolyline(Point3d point, Autodesk.AutoCAD.DatabaseServices.Polyline polyline) {
try {
Point3dCollection intersectPoints = new Point3dCollection();
Point3d startPoint = new Point3d(0.0, point.Y, 0.0);
Line intersectLine = new Line(startPoint, point);

polyline.IntersectWith(intersectLine, Intersect.OnBothOperands, intersectPoints, 0, 0);

return ((intersectPoints.Count % 2) == 1);
}
catch (System.Exception) {
return false;
}
}


Das funktioniert jetzt so, wie ich das wollte. Über die Baumstruktur lege ich pro ineinanderliegender Polylinien eine Hatch an, damit kann ich die Flächen für alle Flächen ausgeben, die ich haben will.

Gruß
mOfl

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

mOfl
Mitglied



Sehen Sie sich das Profil von mOfl an!   Senden Sie eine Private Message an mOfl  Schreiben Sie einen Gästebucheintrag für mOfl

Beiträge: 22
Registriert: 25.09.2010

erstellt am: 09. Nov. 2010 00:16    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hm, gerade fällt mir auf, dass mein Verfahren doch nicht funktioniert, wie ich das wollte. Grund dafür ist, dass Hatch-Entities überhaupt keinen Field-Eintrag "Area" (mehr?) besitzen. Ich lese zwar auf einigen Seiten - sogar inklusive Screenshots - Anleitungen, wie man die Fläche einer Schraffur mithilfe des Area-Fields auslesen kann, aber die von mir (AutoCAD Civil 3D 2010) erzeugte Schraffur hat dieses Feld nicht. Wurde das Feld woanders hin ausgelagert? Oder wie kann ich die Fläche der Schraffuren sonst ermitteln?

Also Folgendes funktioniert für Polylines, aber nicht für Hatches:

Code:
text.SetContentsRtf("%<\\AcExpr abs(%<\\AcObjProp Object(%<\\_ObjId " + id.ToString().Substring(1, id.ToString().Length - 2) + ">%).Area>%) \\f \"%lu2%pr2%ds44\">%");

Da ich die Fields nicht direkt in doubles lesen, sondern nur beim Plotten anzeigen lassen kann, möchte ich ungern den Weg über meine Baumstruktur gehen und Additionen und Subtraktionen der Einzelpolylinien mithilfe von Fields durchführen. Es muss doch einen einfachen Weg geben, die Fläche von Hatches in ObjectARX auszulesen, oder?

Gruß
mOfl

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP


Ex-Mitglied

erstellt am: 09. Nov. 2010 00:51    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat

Hi,

in Ausnahmefällen (z.B. Schraffurgrenzen durch SPLINES) kann es vorkommen, dass AutoCAD bei Schraffuren keine Fläche auswirft. Klick mal die Schraffur an und schau im Eigenschaftsfenster, ob dort die Fläche angezeigt wird oder nicht (Wenn nicht, lade die Zeichnung bitte mal (gezipt) hier hoch, dass ich mir das Werk ansehen kann).


>> Da ich die Fields nicht direkt in doubles lesen, sondern nur beim Plotten anzeigen lassen kann

Das stimmt so nicht, die Flächen werden normalerweise bei jedem Regenerieren (oder Befehl SCHRIFTFELDAKT) aktualisiert. Ausnahme: Du hast an der Variable FIELDEVAL gedreht.

- alfred -

PS: Du bist nicht in ObjectARX, da müsstest Du durch C++ durch. 

------------------
www.hollaus.at

mOfl
Mitglied



Sehen Sie sich das Profil von mOfl an!   Senden Sie eine Private Message an mOfl  Schreiben Sie einen Gästebucheintrag für mOfl

Beiträge: 22
Registriert: 25.09.2010

erstellt am: 09. Nov. 2010 01:45    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Zitat:
PS: Du bist nicht in ObjectARX, da müsstest Du durch C++ durch.  

Man lernt nie aus  Ich war davon ausgegangen, ObjectARX sei die Schnittstelle für VB/C#.

Du hast natürlich recht, was FIELDEVAL angeht. Prinzipiell kann ich die Sachen auch beim Regenerieren anzeigen lassen, aber kann sie leider nicht auslesen. Auch wenn ich die Flächen in AutoCAD sehe, wenn ich den Content eines Textes auslese, ist der "####".

Die Fläche wird auch im Eigenschaftsfenster nicht angezeigt.

Die Zeichnung kann ich dir momentan nicht hochladen, weil es ein reales Projekt ist. Morgen kann ich einen relevanten Ausschnitt daraus erstellen und hochladen, wenn nötig. Ich habe aber mal den relevanten Code hochgeladen: http://pastebin.com/c0igKvgK

Das sind die kompletten Funktionen für das Einfärben und Beschriften von Flächen. Bevor diese Funktionen aufgerufen werden, werden Shape-Dateien über mapimport als geschlossene Polylinien mit Objektdaten geladen. Dann werden alle einzufärbenden Polylinien auf einen eigenen Layer kopiert, der der Funktion fillEntities() übergeben wird. In Folge werden dann alle Polylinien dieses Layers gesucht und in die Baumstruktur gepackt. Lass dich davon nicht erschrecken, die meisten Polylinien haben überhaupt keine innere Begrenzung, sonst meistens eine, maximal zwei. So ineffizient, wie sie scheinen, sind die vielen Schleifen dann nicht.

Den relevanten Teil beider Funktionen habe ich gehighlighted. currentNode ist im Wesentlichen die äußerste Polylinie, alle Child Nodes sind innerhalb liegende Polylinien. Alle obersten Knoten, also alle völlig unabhängigen Flächen, die nicht ineinander liegen, sind in differentAreas gespeichert. Es wird für jede separate Fläche ein Hatch-Objekt erzeugt, alle Polylinien, die innerhalb dieser Fläche liegen, werden demselben Hatch-Objekt zugewiesen. Ich glaube, dadurch werden die Hatch Boundaries festgelegt. Die Entscheidung, was jetzt innen und außen ist, trifft AutoCAD ja korrekt von alleine.

Das ist alles, was ich mit den Schraffuren mache. In drawSizes() wird dann eben auf das Field zugegriffen, aber da die Funktion bei normalen Polylinien problemlos funktioniert, wird es nicht daran liegen, sondern an der Generierung der Schraffur.

Gruß
mOfl

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP


Ex-Mitglied

erstellt am: 09. Nov. 2010 02:20    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat

Hi,

den Code hab ich nicht angesehen (zeitliches Limit die nächsten Tage), nur eine Frage:

Wenn Dein Ziel ist, Flächen gefüllt zu erhalten, aus welchem Grund erzeugst Du bei MAPIMPORT dann Polylinien (und verlierst damit die Zusammenhänge Outline-Island), ich sehe drei Wege, die es leichter machen würden:

a) verwende FDO, da sind Flächenbeschriftungen und Füllungen leichter zu gestalten
b) verwende auch FDO, wenn Du Schraffuren anlegen willst, denn Du kannst damit Deine Ableitung zu Schraffurgrenzen leichter machen (denn die FDO-Elemente haben die Konstellation Outline-Island in sich, ähnlich dem MPolygon)
c) verwende MPolygon statt Polylinien beim Importieren (wie wohl Du recht hast, die API mit MPolygon ist fehlerhaft gewesen, ich meine aber doch, dass diese mit dem letzten ServicePack behoben war).

- alfred -

------------------
www.hollaus.at

mOfl
Mitglied



Sehen Sie sich das Profil von mOfl an!   Senden Sie eine Private Message an mOfl  Schreiben Sie einen Gästebucheintrag für mOfl

Beiträge: 22
Registriert: 25.09.2010

erstellt am: 09. Nov. 2010 17:37    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo alfred,

die Polylinien wähle ich deshalb, weil es mit den MPolygons nicht richtig funktioniert hat. Für etwa die Hälfte der importierten MPolygons ließ sich keine Schraffur erzeugen, weil sie angeblich nicht geschlossen waren.

FDO wollte ich von Anfang an vermeiden, weil es so klang, als würde es den Rahmen dessen, was ich vorhabe, weit sprengen. Polylinien und Schraffuren hörten sich sehr einfach zu implementieren an und sind es ja im Prinzip auch, nur leider funktioniert das Auslesen der Fläche zu unzuverlässig. Damit ich überhaupt mal die korrekte Funktion bekomme, werde ich es jetzt aber doch mal über die Auswertung der ganzen Field-Terme versuchen, also die Baumstruktur entlang gehen, die Terme alle geraden Indizes (von 0 an) über AcExpr addieren, die ungeraden abziehen, dann sollte das richtige Ergebnis rauskommen.

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Anzeige.:

Anzeige: (Infos zum Werbeplatz >>)

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen

nächster neuerer Beitrag | nächster älterer Beitrag
Antwort erstellen


Diesen Beitrag mit Lesezeichen versehen ... | Nach anderen Beiträgen suchen | CAD.de-Newsletter

Administrative Optionen: Beitrag schliessen | Archivieren/Bewegen | Beitrag melden!

Fragen und Anregungen: Kritik-Forum | Neues aus der Community: Community-Forum

(c)2023 CAD.de | Impressum | Datenschutz