Load a STEP file

Use the pychrono.cascade module to load a STEP file saved from a CAD. We provide the .step file in the data/ directory for this example.

Uses PyChrono.

Learn how to:

  • load a STEP file, saved from a 3D CAD.
  • fetch parts from the STEP document and conver into Chrono bodies.
#------------------------------------------------------------------------------
# Name: pychrono example
# Purpose:
#
# Author: Alessandro Tasora
#
# Created: 1/01/2019
# Copyright: (c) ProjectChrono 2019
#------------------------------------------------------------------------------
import pychrono.core as chrono
import pychrono.irrlicht as chronoirr
import pychrono.cascade as cascade
from OCC.Core import TopoDS
print ("Example: Load a STEP file, generated by a CAD")
# The path to the Chrono data directory containing various assets (meshes, textures, data files)
# is automatically set, relative to the default location of this demo.
# If running from a different directory, you must change the path to the data directory with:
#chrono.SetChronoDataPath('path/to/data')
# ---------------------------------------------------------------------
#
# Create the simulation system and add items
#
mysystem = chrono.ChSystemNSC()
# Load a STEP file, containing a mechanism. The demo STEP file has been
# created using a 3D CAD (in this case, SolidEdge v.18).
#
# Create the ChCascadeDoc, a container that loads the STEP model
# and manages its subassembles
mydoc = cascade.ChCascadeDoc()
# load the STEP model using this command:
load_ok = mydoc.Load_STEP(chrono.GetChronoDataFile('cascade/assembly.stp')) # or specify abs.path: ("C:\\data\\cascade\\assembly.stp");
# print the contained shapes
#mydoc.Dump(chrono.GetLog())
# In most CADs the Y axis is horizontal, but we want it vertical.
# So define a root transformation for rotating all the imported objects.
rotation1 = chrono.ChQuaternionD()
rotation1.Q_from_AngAxis(-chrono.CH_C_PI / 2, chrono.ChVectorD(1, 0, 0)) # 1: rotate 90° on X axis
rotation2 = chrono.ChQuaternionD()
rotation2.Q_from_AngAxis(chrono.CH_C_PI, chrono.ChVectorD(0, 1, 0)) # 2: rotate 180° on vertical Y axis
tot_rotation = chrono.ChQuaternionD()
tot_rotation = rotation2 % rotation1 # rotate on 1 then on 2, using quaternion product
root_frame = chrono.ChFrameMovingD(chrono.ChVectorD(0, 0, 0), tot_rotation)
# Retrieve some sub shapes from the loaded model, using
# the GetNamedShape() function, that can use path/subpath/subsubpath/part
# syntax and * or ? wildcards, etc.
mrigidBody1 = 0
mrigidBody2 = 0
if load_ok:
shape1 = TopoDS.TopoDS_Shape()
if (mydoc.GetNamedShape(shape1, "Assem1/body1")):
mbody1 = cascade.ChBodyEasyCascade(shape1, 1000) # density
mysystem.Add(mbody1)
mbody1.SetBodyFixed(True)
# Move the body as for global displacement/rotation (also mbody1 %= root_frame; )
mbody1.ConcatenatePreTransformation(root_frame);
mrigidBody1= mbody1;
else:
print("Warning. Desired object not found in document \n")
shape2 = TopoDS.TopoDS_Shape()
if (mydoc.GetNamedShape(shape2, "Assem1/body2")):
mbody2 = cascade.ChBodyEasyCascade(shape2, 1000) # density
mysystem.Add(mbody2)
# Move the body as for global displacement/rotation (also mbody2 %= root_frame; )
mbody2.ConcatenatePreTransformation(root_frame);
mrigidBody2= mbody2;
else:
print("Warning. Desired object not found in document \n")
else:
print("Warning. Desired STEP file could not be opened/parsed \n")
# Create a revolute joint between the two parts
# as in a pendulum. We assume we already know in advance
# the aboslute position of the joint (ex. we used measuring tools in the 3D CAD)
measured_joint_pos_mm = chrono.ChVectorD(0, 48, 120);
scale = 1. / 1000. # because we use meters instead of mm
joint_pos = chrono.ChVectorD(root_frame.TransformPointLocalToParent(measured_joint_pos_mm * scale))
# transform because we rotated everything
if (mrigidBody1 and mrigidBody2):
my_link.Initialize(mrigidBody1, mrigidBody2, chrono.ChCoordsysD(joint_pos));
mysystem.Add(my_link);
# Create a large cube as a floor.
mfloor = chrono.ChBodyEasyBox(1, 0.2, 1, 1000)
mfloor.SetPos(chrono.ChVectorD(0,-0.3,0))
mfloor.SetBodyFixed(True)
mysystem.Add(mfloor)
mcolor = chrono.ChColorAsset(0.3, 0.3, 0.8)
mfloor.AddAsset(mcolor)
# ---------------------------------------------------------------------
#
# Create an Irrlicht application to visualize the system
#
myapplication = chronoirr.ChIrrApp(mysystem, 'Test', chronoirr.dimension2du(1024,768))
myapplication.AddTypicalSky()
myapplication.AddTypicalLogo(chrono.GetChronoDataFile('logo_pychrono_alpha.png'))
myapplication.AddTypicalCamera(chronoirr.vector3df(0.2,0.2,-0.2))
myapplication.AddTypicalLights()
# ==IMPORTANT!== Use this function for adding a ChIrrNodeAsset to all items
# in the system. These ChIrrNodeAsset assets are 'proxies' to the Irrlicht meshes.
# If you need a finer control on which item really needs a visualization proxy in
# Irrlicht, just use application.AssetBind(myitem); on a per-item basis.
myapplication.AssetBindAll();
# ==IMPORTANT!== Use this function for 'converting' into Irrlicht meshes the assets
# that you added to the bodies into 3D shapes, they can be visualized by Irrlicht!
myapplication.AssetUpdateAll();
# ---------------------------------------------------------------------
#
# Run the simulation
#
myapplication.SetTimestep(0.01)
while(myapplication.GetDevice().run()):
myapplication.BeginScene()
myapplication.DrawAll()
myapplication.DoStep()
myapplication.EndScene()
std::string GetChronoDataFile(const std::string &filename)
Obtain the complete path to the specified filename, given relative to the Chrono data directory (thre...
Definition: ChGlobal.cpp:95
Easy-to-use class for quick creation of rigid bodies with a box shape.
Definition: ChBodyEasy.h:102
Base class for assets that carry basic informations about the surface color for visualization assets.
Definition: ChColorAsset.h:28
Class for a physical system in which contact is modeled using a non-smooth (complementarity-based) me...
Definition: ChSystemNSC.h:29