class GlobalProperties(object): ''' global properties for all topologies ''' def __init__(self, instance): from OCC.GProp import GProp_GProps from OCC.BRepGProp import BRepGProp self.instance = instance self.system = GProp_GProps() _topo_type = self.instance.type if _topo_type == 'face' or _topo_type == 'shell': BRepGProp().SurfaceProperties(self.instance.topo, self.system) elif _topo_type == 'edge': BRepGProp().LinearProperties(self.instance.topo, self.system) elif _topo_type == 'solid': BRepGProp().VolumeProperties(self.instance.topo, self.system) def centre(self): """ :return: centre of the entity """ return self.system.CentreOfMass() def inertia(self): '''returns the inertia matrix''' return self.system.MatrixOfInertia(), self.system.MomentOfInertia() def area(self): '''returns the area of the surface''' return self.system.Mass() def bbox(self): ''' returns the bounding box of the face ''' return get_boundingbox(self.instance.topo)
# original implementation with occ backend import siconos.io.mechanics_io siconos.io.mechanics_io.set_implementation('original') siconos.io.mechanics_io.set_backend('occ') # ball shape ball = BRepPrimAPI_MakeSphere(.15).Shape() ball_props = GProp_GProps() brepgprop_VolumeProperties(ball, ball_props) ball_mass = ball_props.Mass() ball_com = ball_props.CentreOfMass() ball_inertia = ball_props.MatrixOfInertia() ball_I1 = ball_props.MomentOfInertia(gp_Ax1(ball_com, gp_Dir(1, 0, 0))) ball_I2 = ball_props.MomentOfInertia(gp_Ax1(ball_com, gp_Dir(0, 1, 0))) ball_I3 = ball_props.MomentOfInertia(gp_Ax1(ball_com, gp_Dir(0, 0, 1))) print 'ball mass:', ball_mass print 'ball center of mass:', (ball_com.Coord(1), ball_com.Coord(2), ball_com.Coord(3)) print 'ball moment of inertia:', (ball_I1, ball_I2, ball_I3) # the ground ground = BRepPrimAPI_MakeBox(gp_Pnt(-20, -20, 0), 40., 40., .5).Shape() # bowl shape hspherei = BRepPrimAPI_MakeSphere(.9, pi).Shape() hsphereo = BRepPrimAPI_MakeSphere(1., pi).Shape() bowl = BRepAlgoAPI_Cut(hsphereo, hspherei).Shape()
def compute_inertia_and_center_of_mass(shapes, io=None): """ Compute inertia from a list of Shapes. Returns ------- mass center_of_mass inertia inertia_matrix """ from OCC.GProp import GProp_GProps from OCC.BRepGProp import brepgprop_VolumeProperties from OCC.gp import gp_Ax1, gp_Dir from siconos.mechanics import occ system = GProp_GProps() for shape in shapes: iprops = GProp_GProps() if shape.data is None: if io is not None: shape.data = io._shape.get(shape.shape_name, new_instance=True) else: warn('cannot get shape {0}'.format(shape.shape_name)) return None iishape = shape.data ishape = occ.OccContactShape(iishape).data() # the shape relative displacement occ.occ_move(ishape, list(shape.translation) + list(shape.orientation)) brepgprop_VolumeProperties(iishape, iprops) density = None if hasattr(shape, 'mass') and shape.mass is not None: density = shape.mass / iprops.Mass() elif shape.parameters is not None and hasattr(shape.parameters, 'density'): density = shape.parameters.density #print('shape.parameters.density:', shape.parameters.density) else: density = 1. assert density is not None # print("shape", shape.shape_name) # print('density:', density) # print('iprops.Mass():', iprops.Mass()) system.Add(iprops, density) mass = system.Mass() assert (system.Mass() > 0.) computed_com = system.CentreOfMass() gp_mat = system.MatrixOfInertia() inertia_matrix = np.zeros((3, 3)) for i in range(0, 3): for j in range(0, 3): inertia_matrix[i, j] = gp_mat.Value(i + 1, j + 1) I1 = system.MomentOfInertia(gp_Ax1(computed_com, gp_Dir(1, 0, 0))) I2 = system.MomentOfInertia(gp_Ax1(computed_com, gp_Dir(0, 1, 0))) I3 = system.MomentOfInertia(gp_Ax1(computed_com, gp_Dir(0, 0, 1))) inertia = [I1, I2, I3] center_of_mass = np.array( [computed_com.Coord(1), computed_com.Coord(2), computed_com.Coord(3)]) return mass, center_of_mass, inertia, inertia_matrix
def compute_inertia_and_center_of_mass(shapes, mass, io=None): """ Compute inertia from a list of Shapes. """ from OCC.GProp import GProp_GProps from OCC.BRepGProp import brepgprop_VolumeProperties from OCC.gp import gp_Ax1, gp_Dir from siconos.mechanics import occ props = GProp_GProps() for shape in shapes: iprops = GProp_GProps() if shape.data is None: if io is not None: shape.data = io._shape.get(shape.shape_name, new_instance=True) else: warn('cannot get shape {0}'.format(shape.shape_name)) return None iishape = shape.data ishape = occ.OccContactShape(iishape).data() # the shape relative displacement occ.occ_move(ishape, list(shape.translation) + list(shape.orientation)) brepgprop_VolumeProperties(iishape, iprops) density = None if hasattr(shape, 'mass') and shape.mass is not None: density = shape.mass / iprops.Mass() elif shape.parameters is not None and \ hasattr(shape.parameters, 'density'): density = shape.parameters.density else: density = 1. assert density is not None props.Add(iprops, density) assert (props.Mass() > 0.) global_density = mass / props.Mass() computed_com = props.CentreOfMass() I1 = global_density * props.MomentOfInertia( gp_Ax1(computed_com, gp_Dir(1, 0, 0))) I2 = global_density * props.MomentOfInertia( gp_Ax1(computed_com, gp_Dir(0, 1, 0))) I3 = global_density * props.MomentOfInertia( gp_Ax1(computed_com, gp_Dir(0, 0, 1))) inertia = [I1, I2, I3] center_of_mass = np.array( [computed_com.Coord(1), computed_com.Coord(2), computed_com.Coord(3)]) return inertia, center_of_mass