AutoCAD : l'API .NET est parfois un peu compliquée

AutoCAD propose de nombreuses API : ObjectARX, .NET, ActiveX/COM, AutoLISP. Il faut en plus maintenant ajouter l'API Javascript qui est une nouveauté d'AutoCAD 2014. Et parfois, ce qui s'avère très simple dans une des API se révéle très compliqué dans une autre. Prenons par exemple le cas du zoom étendu.

Avec l'API ActiveX et VBA, il suffit de faire :

ThisDrawing.Application.ZoomExtents

Avec l'API .NET, c'est un peu plus compliqué :

Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
    db.UpdateExt(true);

    Point3d min, max;
    var cvport = (short)Application.GetSystemVariable("CVPORT");
    if (db.TileMode || cvport == 0)
    {
        // Espace objet ou espace objet flottant
        min = db.Extmin;
        max = db.Extmax;
    }
    else
    {
        // Espace papier
        min = db.Pextmin;
        max = db.Pextmax;
    }

    using (ViewTableRecord view = doc.Editor.GetCurrentView())
    {
        double screenRatio = (view.Width / view.Height);

        Matrix3d matDCS2WCS = Matrix3d.PlaneToWorld(view.ViewDirection);

        // Décalage de l'origine
        matDCS2WCS = Matrix3d.Displacement(view.Target - Point3d.Origin) 
          * matDCS2WCS;

        // Rotation de la vue
        matDCS2WCS = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) 
          * matDCS2WCS;
        Matrix3d matWCS2DCS = matDCS2WCS.Inverse();

        // Calcule la boite englobante dans le SCA
        var spaceExtents = new Extents3d(min, max);
        var corners = new[]
            {
                new Point3d(spaceExtents.MinPoint.X, spaceExtents.MaxPoint.Y,
                  spaceExtents.MaxPoint.Z),
                new Point3d(spaceExtents.MaxPoint.X, spaceExtents.MaxPoint.Y, 
                  spaceExtents.MaxPoint.Z),
                new Point3d(spaceExtents.MaxPoint.X, spaceExtents.MinPoint.Y, 
                  spaceExtents.MaxPoint.Z),
                new Point3d(spaceExtents.MinPoint.X, spaceExtents.MinPoint.Y,
                  spaceExtents.MaxPoint.Z),
                new Point3d(spaceExtents.MinPoint.X, spaceExtents.MaxPoint.Y,
                  spaceExtents.MinPoint.Z),
                new Point3d(spaceExtents.MaxPoint.X, spaceExtents.MaxPoint.Y,
                  spaceExtents.MinPoint.Z),
                new Point3d(spaceExtents.MaxPoint.X, spaceExtents.MinPoint.Y,
                  spaceExtents.MinPoint.Z),
                new Point3d(spaceExtents.MinPoint.X, spaceExtents.MinPoint.Y,
                  spaceExtents.MinPoint.Z)
            };

        var ext = new Extents3d();
        for (int i = 0; i < corners.Length; i++)
        {
            Point3d p = corners[i].TransformBy(matWCS2DCS);
            if (i == 0)
                ext = new Extents3d(p, p);
            else
                ext.AddPoint(p);
        }

        double width = ext.MaxPoint.X - ext.MinPoint.X;
        double height = ext.MaxPoint.Y - ext.MinPoint.Y;

        if (width > (height * screenRatio)) height = width / screenRatio;

        view.Height = height;
        view.Width = height * screenRatio;

        view.CenterPoint = new Point2d(
            (ext.MinPoint.X + ext.MaxPoint.X) / 2,
            (ext.MinPoint.Y + ext.MaxPoint.Y) / 2
            );
        doc.Editor.SetCurrentView(view);
    }

    tr.Commit();
}

Ouch ! La puissance a un prix. Heureusement, rien ne nous empêche d'utiliser l'API ActiveX en .NET :

Object acadObject = Application.AcadApplication;
acadObject.GetType().InvokeMember("ZoomExtents",
  BindingFlags.InvokeMethod, null, acadObject, null);

Etiquettes:

Add new comment