diff --git a/docs/assemblies.rst b/docs/assemblies.rst index e740bd6d..5dcbe9b9 100644 --- a/docs/assemblies.rst +++ b/docs/assemblies.rst @@ -1,3 +1,5 @@ +.. _assembly: + ########## Assemblies ########## diff --git a/docs/assets/rigid_joints_pipe.png b/docs/assets/rigid_joints_pipe.png new file mode 100644 index 00000000..23c2cb2f Binary files /dev/null and b/docs/assets/rigid_joints_pipe.png differ diff --git a/docs/index.rst b/docs/index.rst index 2ee07091..5cae1aa7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -103,6 +103,7 @@ Table Of Contents objects.rst operations.rst builders.rst + joints.rst assemblies.rst tips.rst import_export.rst diff --git a/docs/joints.rst b/docs/joints.rst new file mode 100644 index 00000000..913f7f69 --- /dev/null +++ b/docs/joints.rst @@ -0,0 +1,102 @@ +###### +Joints +###### + +:class:`~topology.Joint`'s enable Solid and Compound objects to be arranged +relative to each other in an intuitive manner - with the same degree of motion +that is found with the equivalent physical joints. :class:`~topology.Joint`'s always work +in pairs - a :class:`~topology.Joint` can only be connected to another :class:`~topology.Joint` as follows: + ++---------------------------------------+---------------------------------------------------------------------+--------------------+ +| :class:`~topology.Joint` | connect_to | Example | ++=======================================+=====================================================================+====================+ +| :class:`~topology.BallJoint` | :class:`~topology.RigidJoint` | Gimbal | ++---------------------------------------+---------------------------------------------------------------------+--------------------+ +| :class:`~topology.CylindricalJoint` | :class:`~topology.RigidJoint` | Screw | ++---------------------------------------+---------------------------------------------------------------------+--------------------+ +| :class:`~topology.LinearJoint` | :class:`~topology.RigidJoint`, :class:`~topology.RevoluteJoint` | Slider or Pin Slot | ++---------------------------------------+---------------------------------------------------------------------+--------------------+ +| :class:`~topology.RevoluteJoint` | :class:`~topology.RigidJoint` | Hinge | ++---------------------------------------+---------------------------------------------------------------------+--------------------+ +| :class:`~topology.RigidJoint` | :class:`~topology.RigidJoint` | Fixed | ++---------------------------------------+---------------------------------------------------------------------+--------------------+ + +Objects may have many joints bound to them each with an identifying label. All :class:`~topology.Joint` +objects have a ``symbol`` property that can be displayed to help visualize +their position and orientation (the `ocp-vscode `_ viewer +has built-in support for displaying joints). + +.. note:: + The :class:`~build_part.BuildPart` builder will currently over-write joints unless they appear at + the end of the part definition. + +The following sections provide more detail on the available joints and describes how they are used. + +*********** +Rigid Joint +*********** + +A rigid joint positions two components relative to each another with no freedom of movement. When a +:class:`~topology.RigidJoint` is instantiated it's assigned a ``label``, a part to bind to (``to_part``), +and a ``joint_location`` which defines both the position and orientation of the joint (see +:class:`~geometry.Location`) - as follows: + +.. code-block:: python + + RigidJoint(label="outlet", to_part=pipe, joint_location=path.location_at(1)) + +Once a joint is bound to a part this way, the :meth:`~topology.Joint.connect_to` method can be used to +repositioning another part relative to ``self`` which stay fixed - as follows: + +.. code-block:: python + + pipe.joints["outlet"].connect_to(flange_outlet.joints["pipe"]) + +.. note:: + Within a part all of the joint labels must be unique. + +The :meth:`~topology.Joint.connect_to` method only does a one time re-position of a part and does not +bind them in any way; however, putting them into an :ref:`assembly` will maintain there relative locations +as will combining parts with boolean operations or within a :class:`~build_part.BuildPart` context. + +As a example of creating parts with joints and connecting them together, consider the following code where +flanges are attached to the ends of a curved pipe: + +.. image:: assets/rigid_joints_pipe.png + +.. literalinclude:: rigid_joints_pipe.py + +Note how the locations of the joints are determined by the :meth:`~topology.Mixin1D.location_at` method +and how the ``-`` negate operator is used to reverse the direction of the location without changing it's +poosition. Also note that the ``WeldNeckFlange`` class predefines two joints, one at the pipe end and +one at the face end - both of which are shown in the above image (generated by ocp-vscode with the +``render_joints=True`` flag set in the ``show`` function). + +************** +Revolute Joint +************** + +Component rotates around axis like a hinge. + +************ +Linear Joint +************ + +Component moves along a single axis. + +***************** +Cylindrical Joint +***************** + +Component rotates around and moves along a single axis like a screw. + +********** +Ball Joint +********** + +A component rotates around all 3 axes using a gimbal system (3 nested rotations). + +********** +Conclusion +********** + diff --git a/docs/rigid_joints_pipe.py b/docs/rigid_joints_pipe.py new file mode 100644 index 00000000..d7a30960 --- /dev/null +++ b/docs/rigid_joints_pipe.py @@ -0,0 +1,30 @@ +import copy +from build123d import * +from bd_warehouse.flange import WeldNeckFlange +from bd_warehouse.pipe import PipeSection +from ocp_vscode import * + +flange_inlet = WeldNeckFlange(nps="10", flange_class=300) +flange_outlet = copy.copy(flange_inlet) + +with BuildPart() as pipe_builder: + # Create the pipe + with BuildLine(): + path = TangentArc((0, 0, 0), (2 * FT, 0, 1 * FT), tangent=(1, 0, 0)) + with BuildSketch(Plane(origin=path @ 0, z_dir=path % 0)): + PipeSection("10", material="stainless", identifier="40S") + sweep() + + # Add the joints + RigidJoint( + label="inlet", to_part=pipe_builder.part, joint_location=-path.location_at(0) + ) + RigidJoint( + label="outlet", to_part=pipe_builder.part, joint_location=path.location_at(1) + ) + +# Place the flanges at the ends of the pipe +pipe_builder.part.joints["inlet"].connect_to(flange_inlet.joints["pipe"]) +pipe_builder.part.joints["outlet"].connect_to(flange_outlet.joints["pipe"]) + +show(pipe_builder, flange_inlet, flange_outlet, render_joints=True) diff --git a/docs/tutorial_joints.rst b/docs/tutorial_joints.rst index f9560a99..d6de4f81 100644 --- a/docs/tutorial_joints.rst +++ b/docs/tutorial_joints.rst @@ -5,31 +5,7 @@ Joint Tutorial ############## This tutorial provides a step by step guide in using :class:`~topology.Joint`'s as we create -a box with a hinged lid. They allow Solid and Compound objects to be arranged -relative to each other in an intuitive manner - with the same degree of motion -that is found with the equivalent physical joints. :class:`~topology.Joint`'s always work -in pairs - a :class:`~topology.Joint` can only be connected to another :class:`~topology.Joint` as follows: - -+---------------------------------------+---------------------------------------------------------------------+--------------------+ -| :class:`~topology.Joint` | connect_to | Example | -+=======================================+=====================================================================+====================+ -| :class:`~topology.BallJoint` | :class:`~topology.RigidJoint` | Gimbal | -+---------------------------------------+---------------------------------------------------------------------+--------------------+ -| :class:`~topology.CylindricalJoint` | :class:`~topology.RigidJoint` | Screw | -+---------------------------------------+---------------------------------------------------------------------+--------------------+ -| :class:`~topology.LinearJoint` | :class:`~topology.RigidJoint`, :class:`~topology.RevoluteJoint` | Slider or Pin Slot | -+---------------------------------------+---------------------------------------------------------------------+--------------------+ -| :class:`~topology.RevoluteJoint` | :class:`~topology.RigidJoint` | Hinge | -+---------------------------------------+---------------------------------------------------------------------+--------------------+ -| :class:`~topology.RigidJoint` | :class:`~topology.RigidJoint` | Fixed | -+---------------------------------------+---------------------------------------------------------------------+--------------------+ - -Objects may have many joints bound to them each with an identifying label. All :class:`~topology.Joint` -objects have a ``symbol`` property that can be displayed to help visualize -their position and orientation. - -In this tutorial, a box with a hinged lid will be created to illustrate the -use of three different :class:`~topology.Joint` types. +a box with a hinged lid to illustrate the use of three different :class:`~topology.Joint` types. .. image:: assets/tutorial_joint.svg :align: center