Non rectangular viewport and its polyline

When creating a non rectangular pviewport, a polyline is created as well by Bricscad.Is there a way in VB(A) to determine, which polyline belongs to the viewport?Both are on the same layer, but so can other polylines be as well.Is there some relation I can test for?(Could not find anything in xdata)TIA,Arno van Eeuwen

Comments

  • Actually I'm still strugling with this one.

    Does anybody know what is the connection between a non rectangular PViewport and its associated polyline?

    How can the PViewport object tell me wether a viewport is rectangular or not?

     

    TIA

     

     

     

  • Does this lisp help?

     

    (defun c:TestVP ( / )
    (if
    (and
    (progn (graphscr) T)
    (setq result (car (entsel "Selelect viewport: ")))
    (setq resultLst (entget result))
    (progn (textscr) T)
    (= (cdr (assoc 0 resultLst)) "VIEWPORT")
    (princ "\nYes it's a viewport with entity name: \n")
    (princ (cdr (assoc -1 resultLst)))
    (setq clipBoundary (cdr (assoc 340 resultLst)))
    (princ "\nThis viewport is clipped. Boundary data: \n")
    (setq clipBoundaryLst (entget clipBoundary))
    (princ clipBoundaryLst)
    (princ "\nWithin this boundary data you can find this reference to the viewport: \n")
    (setq clipBoundaryLstPart (cadr (member '(102 . "{ACAD_REACTORS") clipBoundaryLst)))
    (princ clipBoundaryLstPart)
    )
    (princ "\nDone! ")
    (princ "\nThis is not a clipped viewport ")
    )
    (princ)
    )

     

     

  • Thanks, Roy.

    Actually I'm trying to achieve this through some kind of COM call in VB(A) or C#.

    I'm not sure the PViewport object is exposing its clip-boundary in COM.

    Currently, I'm searching for a LWPOLY at the same layer and layout as the PVIEWPORT and compare the Boundingboxes. It works but does not feel like an idiot proof method at al...l

    Any other sugestions?

     

  • Hi Arno,

    I do not know the answer you are seeking but I do seem to recall the polyline entity name is stored in the entity data association list with code 340... something like

    (entget (cdr (assoc 340 vp_elist))) will give you the polyline with Lisp.

    I also know the bounding polyline can be on a different layer from the viewport entity.

    Not sure if that helps you at all... I do not know much about COM or C#

     

  • Hi Arno,

     

    I am in the process of wrapping a few global functions for a  .net project I'm working on, one of which is acdbEntGet.. it returns a list of DXF codes and values for a given object. This would certainly work for what you need. Let me know and I will compile and upload what I have.

     

    Dan

  • Hi Daniel,

    sounds very promising; since I'm needing it in C#.Net it would certainly help me.

    Will this be part of your .Net wrapper libraries?

    Cheers,

    Arno

     

     

     

  • "Will this be part of your .Net wrapper libraries?"

     

    Yes I'm adding a namespace RxNet.RxGlobal to house global functions

    that are frequently p/invoked. Some of them may duplicate methods accessible

    via com.. but oh well, the more the merrier : )

     

    Just curious, are you using the libraries?

     

    Daniel

  • Hi Arno,

    I have uploaded the .net wrappers (1.0.0.4) to the developers area. See if this sample gets you started.

     

    [CommandMethod("vptest")]
      public static void vptest()
      {
       AcadApplication application =
         Application.AcadApplication as AcadApplication;
     
       if (application == null)
        throw new System.Exception("Could Not Get Application");
     
       AcadDocument Doc = application.ActiveDocument;
       try
       {
        foreach (AcadEntity e in Doc.ActiveLayout.Block)
        {
         if (e.EntityName.Equals("AcDbViewport"))
         {
          ResultBuffer buf =
           GlobalFunctions.EntGet(new ObjectId(e.ObjectID));
     
          int index = buf.FindIndex(Has340);
          if (index != -1)
          {
           ObjectId VPid = new ObjectId(e.ObjectID);
           ObjectId Entid = (ObjectId)buf[index].Value;
     
           Doc.Utility.Prompt(
             String.Format
              ("\nViewPort Id: {0}, Polyline Id: {1}", VPid, Entid));
     
           //AcadEntity ent = 
           //   Doc.database.ObjectIdToObject(Entid.OldId) as AcadEntity;
          }
         }
        }
       }
       catch (System.Exception ex)
       {
        System.Windows.Forms.MessageBox.Show
         (String.Format
           (":{0},\n:{1}", ex.Message, ex.StackTrace));
       }
      }
     
      internal static bool Has340(TypedValue val)
      {
       return val.TypeCode == 340;
      }

     

     

  • Thanks Daniel.

    I picked up your stuff and see I have to upgrade my 2005 Express to 2008.

    Your example looks cristal clear, I expect it to work as fluent as your .Net wrappers and the TAB tools I picked up from the Swamp earlier this year.

    I've have had a go on the .Net wrappers and they work like  charm.

     

    I'll get back to you.

     

    Arno

    Still having fun @ the Bund?

  • To use the wrappers, you only need VS2005 or .NET 2.0, I do recommend using VS2008 (what I used for the sample)  to take advantage of the new features, such as extension methods

     

    Oh the bund is a real nightmare for the tourists, the whole walkway in front is being rebuilt for the Expo, If you plan to visit before 2010, bring your hardhat : )

  • Hi Daniel,

    After initial struggle with RxNet 10.0.0.4 (Cannot load in V9.3.13 Pro) I found your updated 10.0.0.5 version.

    Loads ok in V9.3.13 and the example works ok , I get two Id's returned from an irregular vieport, so I can take it from there.

    Cool stuff!!

    Thanks,

    Arno

     

      

     

  • For those interested, here's the little extention I made on Daniels example.

    After obtaining the Id of the polyline object, it only takes a few steps to get to the actual polyline object and its coordinates.

    public static void vptest()
    {
    AcadApplication application = Application.AcadApplication as AcadApplication;

    if (application == null)
    throw new System.Exception("Could not get application");

    AcadDocument Doc = application.ActiveDocument;

    try
    {
    foreach (AcadEntity e in Doc.ActiveLayout.Block)
    {
    if (e.EntityName.Equals("AcDbViewport"))
    {
    ResultBuffer buf = GlobalFunctions.EntGet(new ObjectId(e.ObjectID));

    int index = buf.FindIndex(Has340);

    if (index != -1)
    {
    ObjectId VPid = new ObjectId(e.ObjectID);

    ObjectId ENTid = (ObjectId)buf[index].Value;

    Doc.Utility.Prompt(String.Format("\nViewport Id: {0}, Polyline Id: {1}", VPid, ENTid));

    AcadLWPolyline lwPoly = (AcadLWPolyline)Doc.database.ObjectIdToObject((int)ENTid);

    double[] coords = (double[])lwPoly.Coordinates;

    for (int i = 0; i < coords.Length / 2; i ++)
    {
    Doc.Utility.Prompt(String.Format("\nViewport X: {0}, Viewport Y: {1}", coords[i * 2], coords[i * 2 + 1]));
    }
    }
    else
    {
    //Doc.Utility.Prompt(String.Format("\nNo Polyline found for entity {0}", e.EntityName));
    }
    }
    }

    }
    catch (System.Exception ex)
    {
    System.Windows.Forms.MessageBox.Show(String.Format(":{0},\n:{1}", ex.Message, ex.StackTrace));
    }
    }

    internal static bool Has340(TypedValue val)
    {
    return val.TypeCode == 340;
    }

    }

     

     

  • Nice work Arno!

     

    Not sure if this will help in your situation, ... I have added the function GetCurViewportObjectId, that will get the ObjectId of the current active ViewPort

     

    ObjectId vpid = GlobalFunctions.GetCurViewportObjectId();

     

    Daniel

This discussion has been closed.