none
3D Modell um die eigene Achse drehen RRS feed

  • Frage

  • Hallo,

    ich stehe vor einem Problem und weiß nicht mehr weiter.

    ich möchte ein 3D Modell (*.stl) Datei die ich lade um die eigene X/Y/ oder Z-Achse drehen.

    Das drehen funktioniert, nur ist der Drehpunkt irgendwo weit weg vom Modell, ich möchte aber über den Schwerpunkt des Modells drehen.

    Ich habe eine Function eingefügt (GetCenter3DPoint()) die den Schwerpunkt ausrechnet, aber auch mit der funktioniert es nicht, der Teil wird gedreht aber der Drehpunkt ist irgendwo sehr weit weg im Raum.

    Ich denke das Problem liegt darin den "center" parameter des Aufrufs:

    Matrix3D.RotateAt() richtig zu definieren.

    Weiß jemand was zu tun ist?

    Hier der relevante Code:

    --------------------------

    private Model3D Model3d = null;
    private Matrix3D Matrix3D = new Matrix3D();
    public HelixToolkit.Wpf.ModelImporter Model3DImporter { get; set; } = new HelixToolkit.Wpf.ModelImporter();
    public System.Windows.Media.Media3D.ModelVisual3D Viewer3D { get; private set; } = null;

    --------------------------
    Model3d = Model3DImporter.Load(meinestldatei);

    Viewer3D = new System.Windows.Media.Media3D.ModelVisual3D();

    Matrix3D = Viewer3D.Content.Transform.Value;

    axisx = new Vector3D(1, 0, 0);
    anglex = 45;

    Point3D point3d;  
    point3d = new Point3D(0, 0, 0); // point3d = Info.Part.GetCenter3DPoint();
    Matrix3D.RotateAt(new Quaternion(axisx, anglex), point3d);

    Viewer3D.Content.Transform = new MatrixTransform3D(Matrix3D);


    Hier noch der Code für die Schwerpunktermittlung, der ebenfalls nicht funktioniert der Drehpunkt ist immer noch "irgendwo":

           

    public Point3D GetCenter3DPoint(string filepath)
            {

                string[] stldata;
                List<Point3D> verticies = new List<Point3D>();
                Point3D point3d;
                stldata = File.ReadAllLines(filepath);

                counter = 0;
                for (int i = 0; i < stldata.Length; i++)
                {

                    string[] vertex = stldata[i].Split(' ');
                    if (vertex[0] != "vertex")
                        continue;

                    verticies.Add(new Point3D(Double.Parse(vertex[1], CultureInfo.InvariantCulture.NumberFormat), Double.Parse(vertex[2], CultureInfo.InvariantCulture.NumberFormat), Double.Parse(vertex[3], CultureInfo.InvariantCulture.NumberFormat)));
                }        
                return  GetCenterOfVerticies(ref verticies);

            }

    private Point3D GetCenterOfVerticies(ref List<Point3D> verticies)
            {
                //Center of mass of surface
                var s = new Vector3D();
                var areaTotal = 0.0;

                var p1 = verticies[0];
                var p2 = verticies[1];

                for (var i = 2; i < verticies.Count; i++)
                {
                    var p3 = verticies[i];
                    var edge1 = p3 - p1;
                    var edge2 = p3 - p2;

                    var crossProduct = Vector3D.CrossProduct(edge1, edge2);
                    var area = crossProduct.Length / 2;

                    s.X += area * (p1.X + p2.X + p3.X) / 3;
                    s.Y += area * (p1.Y + p2.Y + p3.Y) / 3;
                    s.Z += area * (p1.Z + p2.Z + p3.Z) / 3;

                    areaTotal += area;
                    p2 = p3;
                }

                var point = new Point3D
                {
                    X = s.X / areaTotal,
                    Y = s.Y / areaTotal,
                    Z = s.Z / areaTotal
                };


                return point;
            }

    Vielen Dank im Voraus,

    mfg 

    Viewer3D.Content.Transform = new MatrixTransform3D(Matrix3D);
    Viewer3D.Content.Transform = new MatrixTransform3D(Matrix3D);
    Dienstag, 16. Februar 2021 06:29

Alle Antworten

  • Hallo MaPa82,

    Was für geometrische Körper kommen hier in Betrachtung? Wenn es Polyeder sind, würde ich Dir vorschlagen, die Berechnung anfangs auf das einfachste (Tetraeder) auszuprobieren und überprüfen, ob das Drehen wie gewünscht erfolgt. Im Fall einer Pyramide kannst Du auch zuerst den Schwerpunkt der Grundfläche berechnen, dann den Volumenschwerpunkt abhängig von der Höhe berechnen und die Ergebnisse vergleichen (siehe diesbezüglich: https://de.wikipedia.org/wiki/Geometrischer_Schwerpunkt#Pyramide_und_Kegel)

    Gruß,
    Dimitar


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Mittwoch, 17. Februar 2021 09:17
    Administrator
  • Hallo,

    ich habe bereits vieles probiert nur ist der CenterPoint immer komplett wo anders, ich komme nicht mal annähernd in die Nähe des Schwerpunktes.

    Die Geometrie ist übrigens relativ komplex (teilweise bis zu 100.000 Dreiecke in der STL).

    Aber ganz egal welche STL ich lade, ich schaffe es nicht den Drehpunkt auch nur im Ansatz in die Nähe des Teils zu bekommen, der ist gefühlt Meter weit weg von einem Teil der nur paar mm groß ist ...

    Gibt es evtl. irgendwo ein Beispielsource in dem STL Dateien geladen und gedreht werden können?

    mfg, Mario


    Mittwoch, 17. Februar 2021 17:39
  • Keiner eine Idee?

    Ich komm einfach nicht drauf, mittlerweile schon Stunden verbracht aber ich bekomm es nicht hin :(

    Freitag, 19. Februar 2021 11:35