Sunday, November 15, 2009

(V) New SDO_GEOMETRY <-> Autodesk Map3d 2010

Author: Jonio, Dennis

As I stated in the last post:
  • Given a NetSdoGeometry.sdogeometry decompose it into a “DrawAble(s)”.
    As you would suspect this is mostly code. This is the actor that gets invoked every time DrawAbleSdoGeometry gets instantiated via DrawAbleSdoGeometry(sdogeometry aSDO_GEOMETRY) or the Geometry within an existing DrawAbleSdoGeometry gets changed.

    The todo here is to breakdown and pair SDO_ELEM_INFO elements with SDO_ORDINATES elements. The end result will be at least one DrawAble(s).
    Source code (C#):

    private void DrawAblesFromGeometry()
    {
    sdogeometry g = Geometry;
    int[] elms = g.ElemArrayOfInts;
    decimal[] ords = g.OrdinatesArray;
    int dimensions = g.Dimensionality;
    int OFFSET = 0, nxtOFFSET = 0;
    int ETYPE = 0, nxtETYPE = 0;
    int INTERP = 0, nxtINTERP = 0;
    int ETYPE_plus_INTERP = 0;
    //Just to make it easier to work with
    List elmList = new List();
    for (int _i = 0; _i < elms.Length; )
    {
    TriInts tmp_triplet = new TriInts(elms[_i], elms[_i + 1], elms[_i + 2]);
    elmList.Add(tmp_triplet);
    _i = _i + 3;
    }
    //Iterate through the triplets
    for (int _j = 0; _j < elmList.Count; )
    {
    TriInts wrkrElm = elmList[_j];
    OFFSET = wrkrElm.OFFSET;
    ETYPE = wrkrElm.ETYPE;
    INTERP = wrkrElm.INTERP;
    ETYPE_plus_INTERP = ETYPE + INTERP;
    //Look ahead is required for getting and setting offset into the ordinates array
    if (_j < elmList.Count - 1)
    { nxtOFFSET = elmList[_j + 1].OFFSET; nxtETYPE = elmList[_j + 1].ETYPE; nxtINTERP = elmList[_j + 1].INTERP; }
    else
    { nxtOFFSET = nxtETYPE = nxtINTERP = 0; }
    int len_of_ords = 0;
    if (nxtOFFSET > 0)
    {
    len_of_ords = nxtOFFSET - OFFSET;
    }
    else
    {
    len_of_ords = (ords.Length - OFFSET) + 1;
    }
    int len = 0;
    //Based upon the ETYPE and the INTERPRETATION
    switch (ETYPE)
    {
    case 1:
    if (INTERP > 1)
    {
    DrawAble drawp = new DrawAble(DrawAbleType.Point, dimensions);
    DrawAbleSubComponent drawpc = new DrawAbleSubComponent();
    drawpc.Etype = DrawAbleSubComponentEType.PointCluster;
    drawpc.Elem = new int[] { 0, 1, INTERP };
    drawpc.Ords = new decimal[len];
    Array.Copy(ords, OFFSET - 1, drawpc.Ords, 0, len_of_ords);
    drawp.SubComponents.Add(drawpc);
    this.Drawables.Add(drawp);
    }
    else if (INTERP == 1)
    {
    DrawAble drawp1 = new DrawAble(DrawAbleType.Point, dimensions);
    DrawAbleSubComponent drawp1c = new DrawAbleSubComponent();
    drawp1c.Etype = DrawAbleSubComponentEType.Point;
    drawp1c.Ords = new decimal[len_of_ords];
    Array.Copy(ords, OFFSET - 1, drawp1c.Ords, 0, len_of_ords);
    drawp1.SubComponents.Add(drawp1c);
    this.Drawables.Add(drawp1);
    }
    break;
    case 2:
    DrawAble drawl = new DrawAble(DrawAbleType.Line, dimensions);
    DrawAbleSubComponent drawlc = new DrawAbleSubComponent();
    if (ETYPE_plus_INTERP == (int)DrawAbleSubComponentEType.SimpleLine)
    drawlc.Etype = DrawAbleSubComponentEType.SimpleLine;
    else
    drawlc.Etype = DrawAbleSubComponentEType.SimpleLineAllCurves;
    drawlc.Ords = new decimal[len_of_ords];
    Array.Copy(ords, OFFSET - 1, drawlc.Ords, 0, len_of_ords);
    drawl.SubComponents.Add(drawlc);
    this.Drawables.Add(drawl);
    break;
    case 4:
    DrawAble drawcombo = new DrawAble(DrawAbleType.Line, dimensions);
    DrawAbleSubComponent drawcomboc = new DrawAbleSubComponent();
    drawcomboc.Etype = DrawAbleSubComponentEType.CompoundLine;
    int number_of_subelements = INTERP;
    int final_len_of_elms = (number_of_subelements * 3) + 3;
    int first_OFFSET = OFFSET;
    //The subelements PLUS the header
    int[] redone_elms = new int[final_len_of_elms];
    int redone_n = 0;
    redone_elms[redone_n++] = OFFSET - first_OFFSET;
    redone_elms[redone_n++] = ETYPE;
    redone_elms[redone_n++] = INTERP;
    _j = _j + 1;
    for (int k = 1; k <= number_of_subelements; )
    {
    OFFSET = elmList[_j].OFFSET;
    ETYPE = elmList[_j].ETYPE;
    INTERP = elmList[_j].INTERP;

    redone_elms[redone_n + 0] = OFFSET - first_OFFSET;
    redone_elms[redone_n + 1] = ETYPE;
    redone_elms[redone_n + 2] = INTERP;
    redone_n = redone_n + 3;
    k = k + 1;
    _j = _j + 1;
    }
    // _j is now pointing past this "4" string and we MAY be looking at another drawable
    // We find out by comparing the redone_elms count w/elmList count.
    if ((number_of_subelements + 1) < elmList.Count)
    {
    len_of_ords = elmList[_j].OFFSET - first_OFFSET;
    //We now decrement _j because we did not consume the entire thing.
    _j = _j - 1;
    }
    else
    len_of_ords = (ords.Length - first_OFFSET) + 1;

    drawcomboc.Ords = new decimal[len_of_ords];
    Array.Copy(ords, first_OFFSET - 1, drawcomboc.Ords, 0, len_of_ords);
    //Copy the elms
    drawcomboc.Elem = new int[(number_of_subelements * 3) + 3];
    Array.Copy(redone_elms, 0, drawcomboc.Elem, 0, (number_of_subelements * 3) + 3);
    //Add the component to the drawable
    drawcombo.SubComponents.Add(drawcomboc);
    //Add the drawable
    this.Drawables.Add(drawcombo);
    break;
    case 1003:
    DrawAble drawsurf1003 = new DrawAble(DrawAbleType.Surface, dimensions);
    DrawAbleSubComponent drawsurfc1003 = new DrawAbleSubComponent();
    switch (ETYPE_plus_INTERP)
    {
    case (int)DrawAbleSubComponentEType.SimpleSurfaceOuterRingLine:
    drawsurfc1003.Etype = DrawAbleSubComponentEType.SimpleSurfaceOuterRingLine;
    break;
    case (int)DrawAbleSubComponentEType.SimpleSurfaceOuterRingCircle:
    drawsurfc1003.Etype = DrawAbleSubComponentEType.SimpleSurfaceOuterRingCircle;
    break;
    case (int)DrawAbleSubComponentEType.SimpleSurfaceOuterRingAllCurves:
    drawsurfc1003.Etype = DrawAbleSubComponentEType.SimpleSurfaceOuterRingAllCurves;
    break;
    case (int)DrawAbleSubComponentEType.SimpleSurfaceOuterRingRectangle:
    drawsurfc1003.Etype = DrawAbleSubComponentEType.SimpleSurfaceOuterRingRectangle;
    break;
    default:
    break;
    }
    if (nxtOFFSET == 0)
    len = ords.Length - OFFSET + 1;
    else
    len = Math.Abs(nxtOFFSET - OFFSET);
    drawsurfc1003.Ords = new decimal[len];
    Array.Copy(ords, OFFSET - 1, drawsurfc1003.Ords, 0, len_of_ords);
    drawsurf1003.SubComponents.Add(drawsurfc1003);
    this.Drawables.Add(drawsurf1003);
    break;
    case 2003:
    DrawAbleSubComponent drawsurfc2003 = new DrawAbleSubComponent();
    switch (ETYPE_plus_INTERP)
    {
    case (int)DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine:
    drawsurfc2003.Etype = DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine;
    break;
    case (int)DrawAbleSubComponentEType.SimpleSurfaceInnerRingCircle:
    drawsurfc2003.Etype = DrawAbleSubComponentEType.SimpleSurfaceInnerRingCircle;
    break;
    case (int)DrawAbleSubComponentEType.SimpleSurfaceInnerRingAllCurves:
    drawsurfc2003.Etype = DrawAbleSubComponentEType.SimpleSurfaceInnerRingAllCurves;
    break;
    case (int)DrawAbleSubComponentEType.SimpleSurfaceInnerRingRectangle:
    drawsurfc2003.Etype = DrawAbleSubComponentEType.SimpleSurfaceInnerRingRectangle;
    break;
    default:
    break;
    }
    if (nxtOFFSET == 0)
    len = ords.Length - OFFSET + 1;
    else
    len = Math.Abs(nxtOFFSET - OFFSET);
    drawsurfc2003.Ords = new decimal[len];
    Array.Copy(ords, OFFSET - 1, drawsurfc2003.Ords, 0, len_of_ords);
    bool hasHome = false;
    for (int _i = this.Drawables.Count - 1; _i >= 0; _i--)
    {
    if (Drawables[_i].DrawEtype == DrawAbleType.Surface)
    {
    Drawables[_i].SubComponents.Add(drawsurfc2003);
    hasHome = true;
    break;
    }
    }
    if (hasHome == false)
    OrphanComponents.Add(drawsurfc2003);
    break;
    case 1005:
    case 2005:
    DrawAble drawsurfX005 = new DrawAble(DrawAbleType.Surface, dimensions);
    DrawAbleSubComponent drawsurfcX005 = new DrawAbleSubComponent();
    if (ETYPE == 1005)
    drawsurfcX005.Etype = DrawAbleSubComponentEType.CompoundSurfaceOuterRingLine;
    else
    drawsurfcX005.Etype = DrawAbleSubComponentEType.CompoundSurfaceInnerRingLine;
    number_of_subelements = INTERP;
    final_len_of_elms = (number_of_subelements * 3) + 3;
    first_OFFSET = OFFSET;
    //The subelements PLUS the header
    redone_elms = new int[final_len_of_elms];
    redone_n = 0;
    redone_elms[redone_n++] = OFFSET - first_OFFSET;
    redone_elms[redone_n++] = ETYPE;
    redone_elms[redone_n++] = INTERP;
    _j = _j + 1;
    for (int k = 1; k <= number_of_subelements; )
    {
    OFFSET = elmList[_j].OFFSET;
    ETYPE = elmList[_j].ETYPE;
    INTERP = elmList[_j].INTERP;

    redone_elms[redone_n + 0] = OFFSET - first_OFFSET;
    redone_elms[redone_n + 1] = ETYPE;
    redone_elms[redone_n + 2] = INTERP;
    redone_n = redone_n + 3;
    k = k + 1;
    _j = _j + 1;
    }
    //We must remember to decrement _j because we may not have consumed the entire thing.
    if ((number_of_subelements + 1) < elmList.Count)
    {
    len_of_ords = elmList[_j].OFFSET - first_OFFSET;
    }
    else
    len_of_ords = (ords.Length - first_OFFSET) + 1;

    drawsurfcX005.Ords = new decimal[len_of_ords];
    Array.Copy(ords, first_OFFSET - 1, drawsurfcX005.Ords, 0, len_of_ords);
    //Copy the elms
    drawsurfcX005.Elem = new int[(number_of_subelements * 3) + 3];
    Array.Copy(redone_elms, 0, drawsurfcX005.Elem, 0, (number_of_subelements * 3) + 3);
    //Add the drawable if it is a 1005
    if (drawsurfcX005.Etype == DrawAbleSubComponentEType.CompoundSurfaceOuterRingLine)
    {
    //Add the component to the drawable
    drawsurfX005.SubComponents.Add(drawsurfcX005);
    this.Drawables.Add(drawsurfX005);
    }
    else
    {
    // This is a 2005 and it needs the "nearest" outer ring to live within
    hasHome = false;
    for (int _i = this.Drawables.Count - 1; _i >= 0; _i--)
    {
    if (Drawables[_i].DrawEtype == DrawAbleType.Surface)
    {
    Drawables[_i].SubComponents.Add(drawsurfcX005);
    hasHome = true;
    break;
    }
    }
    if (hasHome == false)
    OrphanComponents.Add(drawsurfcX005);
    }
    //We moved _j ahead ONE(1) to far ... in persuit of the nxtOFFSET.
    //We must decrement it so we land back at real next "header" triplet
    _j = _j - 1;
    break;
    default:
    break;
    }
    _j = _j + 1;
    }// main for loop
    }
  • No comments:

    Post a Comment