How to modify Vertices in LineString (3D) with MDL

Hi everyone,

I am trying to write an MDL for Microstation V8i (Select Series 4) which should transform the heights according to a certain height-modelling for different element-types.

I am using a Loop over all graphical Elements with a callback-function, which first creates an Duplicate of the MSElementDscr-Object

mdlElmdscr_duplicate(&newedP, edP);

first and afterwards calls the specific Transformation-function according to the element-type.

It works already for some Elements, like e.g. for Line_3d-Elements:

Private int HoehTrans_htransLine
(
    MSElementDescr	**edPP		// <=> Zeiger auf MSElementDescr-Objekt
)
  {
    int test1=FALSE, test2=FALSE;
    
    // Height-Transformation
    test1=test_transHPoint(&(*edPP)->el.line_3d.start);
    test2=test_transHPoint(&(*edPP)->el.line_3d.end);

    if(test1==TRUE && test2==TRUE) return TRUE;
    else return FALSE;
  }

The same thing should be done for Line_String_3d-Elements as well with the following Code:

Private int HoehTrans_htransLineString
(
    MSElementDescr	**edPP		// <=> Zeiger auf MSElementDescr-Objekt
)
  {
    int test=FALSE i;
    int pnum;
    DPoint3d** pList;

    // Speicher fuer Punktliste allokieren
    pnum=(*edPP)->el.line_string_3d.numverts;
    pList= (DPoint3d**) calloc(pnum, sizeof(DPoint3d*));
    for(i=0; i<pnum; i++) pList[i]= (DPoint3d*) calloc(1, sizeof(DPoint3d));

    // Hoehen-Transformation
    test=HoehTrans_transHList(&(*edPP)->el.line_string_3d.vertice, pnum);
    
    if(test==TRUE) return TRUE;
    else return FALSE;
  }

The connected height-transformation test-function Looks like this:

Private int test_transHList
(
    DPoint3d** pointPL,			//<=> IN/OUT: zu transformierende DPunkt3d-Liste
    int pnum					// => IN: Anzahl der Punkte in Liste
)
  {
    double dh=150.0;
    int ret=FALSE, i;
    
    if(pointPL!=NULL)
    {
        for(i=0; i<pnum; i++) pointPL[i]->z+=dh;
        ret=TRUE;
    }
    return ret;
  }

My Problem is now, that I get an Compiler-error  in the function "HoehTrans_htransLineString" for the Line

-    test=HoehTrans_transHList(&(*edPP)->el.line_string_3d.vertice, pnum);

that says:

"conversion of Parameter 1 from  'DPoint3d (*)[1]' in 'DPoint3d **' not possible"

Because the number of Vertices in the Element is not only "ONE", why  is the '(&(*edPP)->el.line_string_3d.vertice'-Parameter of the LineString-Element not  a field-pointer 'DPoint3d**' ??

Did I understand something wrong, or is it just a simple error in the Code?

In case of the Line-Element I rewrite finally in the callback-function the changed MSElementDscr-Object to file using and would like to do that with the LineString in the same way:

mdlElmdscr_rewrite(newedP, NULL, filePos);

Many thanks in advance for your help!

Best regards,

Ines Wieland

Parents
  • The connected height-transformation test-function

    You're digging too deep into the element structure.  Use the tools available to you that use the power of the API.  The key word in your above statement is 'transformation'.  You can use a Transform to move any type of element.

    In other words, don't do this...

    double dh=150.0;
    int ret=FALSE, i;
        
    if(pointPL!=NULL)
    {
      for(i=0; i<pnum; i++) pointPL[i]->z+=dh;
      ret=TRUE;
    }

    Prefer to make a transform and apply it to your element...

    #include <mselmdsc.fdf>
    #include <mstmatrx.fdf>
    Transform transform;
    mdlTMatrix_getIdentity (&transform);
    const double elevate = 150.0;
    DPoint3d offset = { 0., 0., elevate };
    mdlTMatrix_setTranslation (&transform, &offset);

    ...

    mdlElmdscr_transform (newedP, &transform);

    Note that this approach is higher-level and you don't need to know about the element vertices or how they are stored.

     
    Regards, Jon Summers
    LA Solutions

  • Hi Jon,

    thanks for your answer, but you got me wrong: I only used this simple test-function (with only adding a constant height), because the real function is much more complicate and depending on the position of each point, so there is no possibility to move the whole element, but to adjust the height for each coordinate.

    The way you described is already used for Point-Elements (like Cells and Texts), but the height-correction varies in the area, like an area-function dh=f(x,y), which is already implemented, therefore for Lines, Linestrings, Shapes ... I need to manipulate the height of each vertex separateley

    Best regards,

    Ines Wieland

  • I need to manipulate the height of each vertex separateley

    My earlier comment still stands: use a higher-level C++ approach and eschew the C-style memory allocation.

    Read this article about the C++ standard library and using std::vector<DPoint3d>.

    #include <vector>   //	Standard Library header for vector template class
    typedef std::vector<DPoint3d>   DPoint3dCollection;  //	typedef clarifies subsequent code
    
    void ExtractPoints (MSElement const* linearElement, DgnModelRefP modelRef)
    {
      int pointCount   = mdlLinear_getPointCount (linearElement);
      DPoint3dCollection  points (pointCount);
      //	Ensure that the vector knows how many points it contains
      points.resize (pointCount);
      if (SUCCESS == mdlLinear_extract (&points[0], &pointCount, linearElement, modelRef))
      {
        // Do something with points ...
        for (int i = 0; i != pointCount; ++i)
        {
          DPoint3d& point = points [i];
          point.z = 1234.;
        }
      }
      //  No need to free() anything
    }

     
    Regards, Jon Summers
    LA Solutions

    Answer Verified By: Ines Wieland 

  • Private int HoehTrans_htransLine
    (
    MSElementDescr **edPP // <=> Zeiger auf MSElementDescr-Objekt
    )
    {
    int test1=FALSE, test2=FALSE;

    // Height-Transformation
    test1=test_transHPoint(&(*edPP)->el.line_3d.start);
    test2=test_transHPoint(&(*edPP)->el.line_3d.end);

    if(test1==TRUE && test2==TRUE) return TRUE;
    else return FALSE;
    }

    ^ The serious problem with this approach is that it doesn't update line element's range, so now you have a line element with end points that are potentially outside it's range and that will be the source of all kinds of problems.

    As Jon points out, the standard approach to modification is to extract the information, update it, then feed it back to a create function where you supply the original element as the template.

    HTH

    -B



Reply
  • Private int HoehTrans_htransLine
    (
    MSElementDescr **edPP // <=> Zeiger auf MSElementDescr-Objekt
    )
    {
    int test1=FALSE, test2=FALSE;

    // Height-Transformation
    test1=test_transHPoint(&(*edPP)->el.line_3d.start);
    test2=test_transHPoint(&(*edPP)->el.line_3d.end);

    if(test1==TRUE && test2==TRUE) return TRUE;
    else return FALSE;
    }

    ^ The serious problem with this approach is that it doesn't update line element's range, so now you have a line element with end points that are potentially outside it's range and that will be the source of all kinds of problems.

    As Jon points out, the standard approach to modification is to extract the information, update it, then feed it back to a create function where you supply the original element as the template.

    HTH

    -B



Children
No Data