×
INTELLIGENT WORK FORUMS
FOR ENGINEERING PROFESSIONALS

Log In

Come Join Us!

Are you an
Engineering professional?
Join Eng-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Eng-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

mass properties problem

mass properties problem

mass properties problem

(OP)
Hello,
  I'm trying to write a C# program to get the mass properties of a selected subassembly in a large assembly.  I thought I was following the documentation properly, but I run into one of two problems:
the "AddBodies" function for a mass property object throws an exception if I use the type "swBodyType_e.swSolidBody" as an input.

the mass value returned is that for the entire assembly instead of the added part if I use the type "swBodyType_e.swGeneralBody".

I've attached the function below.
---------
private void APIexample(SldWorks swApp)
{
  try
  {
    ModelDoc2 swModel;
    ModelDocExtension swDocExt;
    MassProperty swMass;
    SelectionMgr swSelMgr;
    Component2 swComp;

    swModel = (ModelDoc2)swApp.ActiveDoc;
    swDocExt = (ModelDocExtension)swModel.Extension;
    swMass = (MassProperty)swDocExt.CreateMassProperty();
    swSelMgr = (SelectionMgr)swModel.SelectionManager;
    swComp = (Component2)swSelMgr.GetSelectedObjectsComponent2(1);
                
    int type = (int)swBodyType_e.swSolidBody;
    //This is the line that fails...
    swMass.AddBodies(swComp.GetBodies2(type));
    MessageBox.Show("Mass: " + swMass.Mass);
  }
  catch (Exception e)
  {
    MessageBox.Show(e.Message);
  }
}
---------
Thanks,
--Tyler

RE: mass properties problem

The Sub-Assembly itself doesn't contain the bodies. You should traverse the assembly, find the Part Components and call this method.

Your swComp.GetBodies2(type) returns NULL. Just for check preselect the Part Component and the code will work correct.

For traversing use Component2::GetChildren method and recursively call it until the component haven't the children (that means it is a Part based component and you can get the bodies).

Please refer the API Help. There are several examples of Traversing the Assembly.

Artem Taturevich
CSWP

RE: mass properties problem

(OP)
  So actually I had been selecting parts instead of subassemblies, I don't think that was the problem.  GetBodies2 would return an object array with a couple elements, but when I call AddBodies with that array, it throws the exception.. "Attempted to read or write protected memory.  This is often
an indication that other memory is corrupt".  

  I actually do have traversal code you recommended, but came up with this example to isolate the problem getting the mass of specific parts, which I still can't seem to figure out.

RE: mass properties problem

(OP)
Artem,
  So the source that I received didn't quite work for me... Sometimes it will only return the total mass of the entire assembly instead of the selected part (for instance, when I select a single part), and other times it will just throw an exception "Object reference not set to an instance of an object".  

  If this worked for you, I'm baffled.  Maybe something about working with Visual Studio 2008?  Something about working with Solidworks 2009?  *shrug*

RE: mass properties problem

Tyler,

It is really strange. I've created this Addin in VS 2008 and tested with SolidWorks 2009.

BTW. What the line where you have received the "Object reference not set to an instance of an object" exception?

Could you please attach some sample assembly and post what mass values you are expected to have on correspondings sub-assemblies/parts?

Artem Taturevich
CSWP

RE: mass properties problem

(OP)
Artem,
So the exception appears to be that GetBodies2 will return null if there are no bodies associated with a bottom level feature (maybe a suppressed part?), so you can't get the length of a null object array.  No biggie there...

however, the mass properties never update to the selected bodies, it always just returns the mass for the entire assembly.  

I've attached a sample assembly for this:
I should get 110.93 grams for the dish,
522597.02 grams for the sat2 subassembly,
133500.00 grams for each panel within the sat2 subassembly,
255597.02 grams for the body within the sat2 subassembly.

No matter what I select, I get 522.707958041958 kg returned, which equals the sum of all the parts.  The correct number of selected bodies is returned though, and when I run through it with the stepper, I can see that it adds the bodies ok.  Just not the right output number.

--Tyler

RE: mass properties problem

Tyler,

Thank you for the clarification. Now I can see the issue.

You can use the following workaround. Create the mass properties object not from the Entire Assembly's model doc but from the Component's model doc.

Just change the try-catch code snippet in the GetMass function to the following code snippet:

- - - - - -
IModelDoc2 swModel;
IModelDocExtension swDocExt;
IMassProperty swMass;
ISelectionMgr swSelMgr;
IComponent2 swComp;

swModel = this.iSwApp.IActiveDoc2;
swDocExt = swModel.Extension;
                
swSelMgr = swModel.ISelectionManager;
swComp = (Component2)swSelMgr.GetSelectedObjectsComponent2(1);
swMass = swComp.IGetModelDoc().Extension.CreateMassProperty();
GetCompBodies(swComp);
bool bRet = swMass.AddBodies(this.swBodies);

this.iSwApp.SendMsgToUser("Bodies: " + this.swBodies.Count + "; Overall Mass: " + swMass.Mass.ToString());
- - - - - -

This should fix the issue. With this modification I get the results exactly as you posted.

Hope this help.

Artem Taturevich
CSWP

RE: mass properties problem

(OP)
Thanks Artem! this gets me 90% of the way to what I need.  It seems that the swMass.AddBodies has no effect on the mass properties... so if I want to combine the properties of two distinct selected components, I'm not quite sure how to do it.    But at least I could manually add the masses of multiple mass property objects (gotta think about how to do the inertia matrix though) If you have any ideas or if I find something, I'll keep monitoring this thread.

Thanks again,
--Tyler

RE: mass properties problem

Hi Tyler,

I think I understand the problem with mass properties from the Top Assembly.

The MassProperties::AddBodies method expects an array of bodies as the parameter while we have passed an List object. In this case SolidWorks considers it as NULL value and as mentioned in API Help discards this call and calculates the overall mass of the document.

So to fix this issue all we need is convert the list value to array using the List<>::ToArray method. Like the following line:

...
bool bRet = swMass.AddBodies(this.swBodies.ToArray());
...

So the mass properties object can be retrieved from the Top Level Document like in the first version of the sample and bodies will be added correctly.

Please take a look at the following modified version of the GetMass function. BTW. It supports the multi-components selection.

- - - - - - - - - -
public void GetMass()
{
    this.swBodies = new List<IBody2>();

    IModelDoc2 swModel;
    IModelDocExtension swDocExt;
    IMassProperty swMass;
    ISelectionMgr swSelMgr;
    List<IComponent2> swComp = new List<IComponent2>();

    swModel = this.iSwApp.IActiveDoc2;
    swDocExt = swModel.Extension;
    swMass = swDocExt.CreateMassProperty();
    swSelMgr = swModel.ISelectionManager;

    for (int i = 0; i < swSelMgr.GetSelectedObjectCount2(-1); i++ )
    {
        IComponent2 curComp = swSelMgr.GetSelectedObjectsComponent2(i + 1) as IComponent2;
        //To refrain from components repetition in case the different entities from one component are selected
        if (!swComp.Contains(curComp))
        {
            swComp.Add(curComp);
         
        }
            
        for (int i = 0; i < swComp.Count; i++)
        {
            GetCompBodies(swComp[i]);
        }

        bool bRet = swMass.AddBodies(this.swBodies.ToArray());

        this.iSwApp.SendMsgToUser("Bodies: " + this.swBodies.Count + "; Overall Mass: " + swMass.Mass.ToString());

        double[] axesOfIntertia = (double[])swMass.get_PrincipleAxesOfInertia(1);
        double[] momentOfInertia = (double[])swMass.PrincipleMomentsOfInertia;

}
- - - - - - - - - -

Artem Taturevich
CSWP

RE: mass properties problem

(OP)
Thanks Artem, it works great!

I wonder if that means the main reason my original code didn't work was a casting problem?  Funny way to express itself.

Thanks for the help, I've been banging my head against this one for far too long.

--Tyler

RE: mass properties problem

>> I wonder if that means the main reason my original code didn't work was a casting problem?

I don't think so. It isn't look like the casting problem.

Artem Taturevich
CSWP

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Eng-Tips Forums free from inappropriate posts.
The Eng-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Eng-Tips forums is a member-only feature.

Click Here to join Eng-Tips and talk with other members!


Resources