[CONNECT C++] How to programatically drop a parametric cell from native C++

The Drop Element tool will drop a parametric cell into it's sub-elements if I check the Application Elements option.  Is there a native C++ API that will let me do this from code?

Parents
  • Hi John,

    at first, please follow the best practices and specify what MicroStation version do you use. There have been (I guess) 17 versions of CE released so far, so to say "CONNECT" only is just not enough.

    I see my Drop Element parameters are different (I have extra "Solids" option) in CE Update 14.2 version.

    The Drop Element tool will drop a parametric cell into it's sub-elements if I check the Application Elements option

    I think it does not. Based on testing I did, when only Application Elements option is applied, Parametric solid is converted to SmartSolid, but it's not dropped to sub elements.

    Using Drop Element again, SmartSolid can be converted to wireframe or surfaces.

    Is there a native C++ API that will let me do this from code?

    Did you try to search (at least) this forum? Different aspects of parametric solids geometry and how to drop it has been discussed several times including code snippets (see e.g. this discussion).

    I am quite sure the right way is to use ElementGraphicsProcessor and to process retrieved data in a way that suits the best your needs (e.g. to use DraftingElementSchema to create new elements).

    With regards,

      Jan

  • Hello Jan,

    I am using:

    MicroStation CONNECT Edition
    10.14.0.109

    MicroStation CONNECT Edition SDK
    10.14.00.111

    For my test I have placed a 2D parametric cell into a 2D dgn file.   When I use the Drop Element tool with Application Elements checked I see it does drop it into its sub elements.  Perhaps 3d has different behavior?  Or perhaps the Drop Element tool has different behavior with other versions of MicroStation?

    After reading Jon's suggestions I was able to cook up the following code snippet.  I verified that the ElementAgenda returned from the Drop contains the sub elements.  This is the first half of what I wanted to achieve.  My ultimate goal was to identify the constraints that are applied to each of the sub components.  I haven't yet tracked down an API that will give me that information.  Perhaps there isn't one.  Or perhaps this information is encoded as either an ECInstance or ECRelationship of some sort on the element?


    void Foo (MSElementDescrP edP)    
        {
        // Only process parametric cells (type 106)
        if (106 != mdlElement_getType (&edP->el))
            return;
    
        // Create an in-memory duplicate of the parametric cell
        MSElementDescrP duplicate = NULL;
        mdlElmdscr_duplicateSingle (&duplicate, edP);        
        DgnPlatform::ElementHandle eh (duplicate, true, false);
    
        DisplayHandlerP displayHandler  = eh.GetDisplayHandler ();
        if (NULL == displayHandler)
            return;
    
        // Drop the parametric cell into its sub elements
        DropGeometryPtr dropGeometry = DropGeometry::Create ();
        dropGeometry->SetOptions (DropGeometry::OPTION_AppData);
        ElementAgenda agenda;
        if (SUCCESS != displayHandler->Drop (eh, agenda, *dropGeometry))
            return;
    
        // Loop over the sub elements	
        ElementHandleCP first = agenda.GetFirstP();
    	ElementHandleCP end = first + agenda.GetCount();
    
    	for (ElementHandleCP curr = first; curr < end; curr++)
            wprintf (L"elementType = %d\n", curr->GetElementType ());
    
        // Free the duplicate 
        mdlElmdscr_freeAll (&duplicate);
        }
    

  • Hi John,

    For my test I have placed a 2D parametric cell into a 2D dgn file.

    Ok, I automatically thought about 3D solids ;-)

    Do you happen to know if there is an API that will return to me the constraints that are applied to any of my sub elements? 

    It's a new question, so please ask in a new thread!

    BTW Jon answered this question already, because I guess e.g. ParametricCellDefinition should provide you information how parametric cell is defined.

    Or perhaps this information is encoded as either an ECInstance or ECRelationship of some sort on the element?

    Yes, parameters are stored as EC data.

    In my opinion it's always worth to provide real example to make the situation and context clear.

    Regards,

      Jan

  • Hello Jan,

    ParametricCellDefintion doesn't help in this case. See snippet from ParametricModeling.h, below.  One can readily retrieve a set of these for a given parametric cell.  This structure contains all the information about a parameter but it does not know the element that it was applied to.

    Brien indicates (below) that constraints are applied to topological entities, not elements.  That makes sense.  However, when you select an item in MicroStation that has constraints applied you will see those constraints displayed in a highlight color.  So it appears MicroStation somehow knows how to determine which constraints were applied to each element.  

    -- John M.

    struct ParameterDefinition
        {
    protected:
    
        enum Flags
            {
            kFlag_None                  = 0,
            kFlag_DefinitionScope       = 1 << 0,
            kFlag_Hidden                = 1 << 1,
            kFlag_DomainParameter       = 1 << 2,
            kFlag_Calculated            = 1 << 3,
            };
    
        WString             m_displayLabel;
        WString             m_accessString;
        ParameterType       m_type;
        Flags               m_flags;
    
        bool                GetFlag (Flags flag) const      { return flag == (m_flags & flag); }
        void                SetFlag (Flags flag, bool on)   { m_flags = static_cast<Flags> (on ? (m_flags | flag) : (m_flags & (~flag))); }
    public:
        //! Default-constructor. Produces a ParameterDefinition of type "Unknown".
        DGNPLATFORM_EXPORT ParameterDefinition();
        //! Copy-constructor
        DGNPLATFORM_EXPORT ParameterDefinition (ParameterDefinitionCR other);
    
        //! Returns the user-visible parameter name
        WCharCP             GetDisplayLabel() const { return m_displayLabel.c_str(); }
        //! Returns the internal access string which is used to refer to the parameter in code
        WCharCP             GetAccessString() const { return m_accessString.c_str(); }
        //! Returns the parameter type
        ParameterType       GetType() const         { return m_type; }
    
        //! If true, when the parametric model is placed as a cell, the value of this parameter cannot be overridden per-cell.
        bool                IsDefinitionScope() const   { return GetFlag (kFlag_DefinitionScope); }
        //! If true, when the parametric model is placed as a cell, this parameter will not be shown as a property of the cell.
        bool                IsHidden() const            { return GetFlag (kFlag_Hidden); }
        //! If true, this parameter originates from a pre-defined ECClass supplied by the creator of the component.
        bool                IsDomainParameter() const   { return GetFlag (kFlag_DomainParameter); }
        //! If true, this parameter's value is calculated using an expression, and otherwise treated as read-only
        bool                IsCalculated() const        { return GetFlag (kFlag_Calculated); }
    
        //! Sets the user-visible parameter name
        void                SetDisplayLabel (WCharCP label)             { m_displayLabel = label; }
        //! Sets whether this parameter will be hidden when the parametric model is placed as a cell
        void                SetIsHidden (bool hidden)                   { SetFlag (kFlag_Hidden, hidden); }
        //! Sets whether this parameter's value is not allowed to be overridden when the parametric model is placed as a cell
        void                SetDefinitionScope (bool isDefinitionScope) { SetFlag (kFlag_DefinitionScope, isDefinitionScope); }
        //! Changes the type of this parameter.
        DGNPLATFORM_EXPORT ParameterStatus  SetType (ParameterType type);
        //! Sets value of a parameter
        DGNPLATFORM_EXPORT bool             SetVariableValue(IParameterValuesR dest, WStringCR input, DgnModelR model, double unitFactor);
        //! Parses parameter property value and store it in domain parameter property
        bool                                ParsePropertyValue(ECN::ECValueR v, ECN::IECInstanceCR props, WCharCP accessString, WCharCP input);
        };

Reply
  • Hello Jan,

    ParametricCellDefintion doesn't help in this case. See snippet from ParametricModeling.h, below.  One can readily retrieve a set of these for a given parametric cell.  This structure contains all the information about a parameter but it does not know the element that it was applied to.

    Brien indicates (below) that constraints are applied to topological entities, not elements.  That makes sense.  However, when you select an item in MicroStation that has constraints applied you will see those constraints displayed in a highlight color.  So it appears MicroStation somehow knows how to determine which constraints were applied to each element.  

    -- John M.

    struct ParameterDefinition
        {
    protected:
    
        enum Flags
            {
            kFlag_None                  = 0,
            kFlag_DefinitionScope       = 1 << 0,
            kFlag_Hidden                = 1 << 1,
            kFlag_DomainParameter       = 1 << 2,
            kFlag_Calculated            = 1 << 3,
            };
    
        WString             m_displayLabel;
        WString             m_accessString;
        ParameterType       m_type;
        Flags               m_flags;
    
        bool                GetFlag (Flags flag) const      { return flag == (m_flags & flag); }
        void                SetFlag (Flags flag, bool on)   { m_flags = static_cast<Flags> (on ? (m_flags | flag) : (m_flags & (~flag))); }
    public:
        //! Default-constructor. Produces a ParameterDefinition of type "Unknown".
        DGNPLATFORM_EXPORT ParameterDefinition();
        //! Copy-constructor
        DGNPLATFORM_EXPORT ParameterDefinition (ParameterDefinitionCR other);
    
        //! Returns the user-visible parameter name
        WCharCP             GetDisplayLabel() const { return m_displayLabel.c_str(); }
        //! Returns the internal access string which is used to refer to the parameter in code
        WCharCP             GetAccessString() const { return m_accessString.c_str(); }
        //! Returns the parameter type
        ParameterType       GetType() const         { return m_type; }
    
        //! If true, when the parametric model is placed as a cell, the value of this parameter cannot be overridden per-cell.
        bool                IsDefinitionScope() const   { return GetFlag (kFlag_DefinitionScope); }
        //! If true, when the parametric model is placed as a cell, this parameter will not be shown as a property of the cell.
        bool                IsHidden() const            { return GetFlag (kFlag_Hidden); }
        //! If true, this parameter originates from a pre-defined ECClass supplied by the creator of the component.
        bool                IsDomainParameter() const   { return GetFlag (kFlag_DomainParameter); }
        //! If true, this parameter's value is calculated using an expression, and otherwise treated as read-only
        bool                IsCalculated() const        { return GetFlag (kFlag_Calculated); }
    
        //! Sets the user-visible parameter name
        void                SetDisplayLabel (WCharCP label)             { m_displayLabel = label; }
        //! Sets whether this parameter will be hidden when the parametric model is placed as a cell
        void                SetIsHidden (bool hidden)                   { SetFlag (kFlag_Hidden, hidden); }
        //! Sets whether this parameter's value is not allowed to be overridden when the parametric model is placed as a cell
        void                SetDefinitionScope (bool isDefinitionScope) { SetFlag (kFlag_DefinitionScope, isDefinitionScope); }
        //! Changes the type of this parameter.
        DGNPLATFORM_EXPORT ParameterStatus  SetType (ParameterType type);
        //! Sets value of a parameter
        DGNPLATFORM_EXPORT bool             SetVariableValue(IParameterValuesR dest, WStringCR input, DgnModelR model, double unitFactor);
        //! Parses parameter property value and store it in domain parameter property
        bool                                ParsePropertyValue(ECN::ECValueR v, ECN::IECInstanceCR props, WCharCP accessString, WCharCP input);
        };

Children