mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-05 18:20:46 -08:00
Refactored make_instance to Shape/copy & added docs
This commit is contained in:
parent
eaf7267089
commit
b0fc9bfdfd
3 changed files with 8326 additions and 18 deletions
|
|
@ -68,6 +68,57 @@ and now the screw is part of the assembly.
|
||||||
├── outer hinge Hinge at 0x7fc9292c3f40, Location(p=(-150, 60, 50), o=(90, 0, 90))
|
├── outer hinge Hinge at 0x7fc9292c3f40, Location(p=(-150, 60, 50), o=(90, 0, 90))
|
||||||
└── M6 screw Compound at 0x7fc8ee235310, Location(p=(-157, -40, 70), o=(-0, -90, -60))
|
└── M6 screw Compound at 0x7fc8ee235310, Location(p=(-157, -40, 70), o=(-0, -90, -60))
|
||||||
|
|
||||||
|
*********************************
|
||||||
|
Shallow vs. Deep Copies of Shapes
|
||||||
|
*********************************
|
||||||
|
|
||||||
|
Build123d supports the standard python ``copy`` module which provides two different types of
|
||||||
|
copy operations ``copy.copy()`` and ``copy.deepcopy()``.
|
||||||
|
|
||||||
|
Build123d's implementation of ``deepcopy()`` for the ``Shape`` class (e.g. ``Solid``, ``Face``, etc.)
|
||||||
|
does just that, creates a complete copy of the original all the way down to the CAD object.
|
||||||
|
``deepcopy`` is therefore suited to the case where the copy will be subsequently modified to
|
||||||
|
become its own unique item.
|
||||||
|
|
||||||
|
However, when building an assembly a common use case is to include many instances of an
|
||||||
|
object, each one identical but in a different location. This is where ``copy.copy()`` is
|
||||||
|
very useful as it copies all of the ``Shape`` except for the actual CAD object
|
||||||
|
which instead is a reference to the original (OpenCascade refers this as a ``TShape``). As
|
||||||
|
it's a reference any changes to the original will be seen in all of the shallow copies.
|
||||||
|
|
||||||
|
Consider this example where 100 screws are added to an assembly:
|
||||||
|
|
||||||
|
.. image:: reference_assembly.svg
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
screw = Compound.import_step("M6-1x12-countersunk-screw.step")
|
||||||
|
locs = HexLocations(6, 10, 10).local_locations
|
||||||
|
|
||||||
|
screw_copies = [copy.deepcopy(screw).locate(loc) for loc in locs]
|
||||||
|
copy_assembly = Compound(children=screw_copies)
|
||||||
|
copy_assembly.export_step("copy_assembly.step")
|
||||||
|
|
||||||
|
which takes about 5 seconds to run (on an older computer) and produces
|
||||||
|
a file of size 51938 KB. However, if a shallow copy is used instead:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
screw = Compound.import_step("M6-1x12-countersunk-screw.step")
|
||||||
|
locs = HexLocations(6, 10, 10).local_locations
|
||||||
|
|
||||||
|
screw_references = [copy.copy(screw).locate(loc) for loc in locs]
|
||||||
|
reference_assembly = Compound(children=screw_references)
|
||||||
|
reference_assembly.export_step("reference_assembly.step")
|
||||||
|
|
||||||
|
this takes about ¼ second and produces a file of size 550 KB - just over
|
||||||
|
1% of the size of the ``deepcopy()`` version and only 12% larger than the
|
||||||
|
screw's step file.
|
||||||
|
|
||||||
|
Using ``copy.copy()`` to create references to the original CAD object
|
||||||
|
for assemblies can substantially reduce the time and resources used
|
||||||
|
to create and store that assembly.
|
||||||
|
|
||||||
************************
|
************************
|
||||||
Shapes are Anytree Nodes
|
Shapes are Anytree Nodes
|
||||||
|
|
|
||||||
8260
docs/reference_assembly.svg
Normal file
8260
docs/reference_assembly.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.5 MiB |
|
|
@ -2989,8 +2989,19 @@ class Shape(NodeMixin):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __copy__(self) -> Shape:
|
def __copy__(self) -> Shape:
|
||||||
"""Return copy of self"""
|
"""Return shallow copy or reference of self
|
||||||
return copy.deepcopy(self, None)
|
|
||||||
|
Create an copy of this Shape that shares the underlying TopoDS_TShape.
|
||||||
|
|
||||||
|
Used when there is a need for many objects with the same CAD structure but at
|
||||||
|
different Locations, etc. - for examples fasteners in a larger assembly. By
|
||||||
|
sharing the TopoDS_TShape, the memory size of such assemblies can be greatly reduced.
|
||||||
|
|
||||||
|
Changes to the CAD structure of the base object will be reflected in all instances.
|
||||||
|
"""
|
||||||
|
reference = copy.deepcopy(self)
|
||||||
|
reference.wrapped.TShape(self.wrapped.TShape())
|
||||||
|
return reference
|
||||||
|
|
||||||
def copy(self) -> Shape:
|
def copy(self) -> Shape:
|
||||||
"""Here for backwards compatibility with cq-editor"""
|
"""Here for backwards compatibility with cq-editor"""
|
||||||
|
|
@ -3001,19 +3012,6 @@ class Shape(NodeMixin):
|
||||||
)
|
)
|
||||||
return copy.deepcopy(self, None)
|
return copy.deepcopy(self, None)
|
||||||
|
|
||||||
def make_instance(self) -> Shape:
|
|
||||||
"""Create an instance of this Shape that shares the underlying TopoDS_TShape.
|
|
||||||
|
|
||||||
Used when there is a need for many objects with the same CAD structure but at
|
|
||||||
different Locations, etc. - for examples fasteners in a larger assembly. By
|
|
||||||
sharing the TopoDS_TShape, the memory size of such assemblies can be greatly reduced.
|
|
||||||
|
|
||||||
Changes to the CAD structure of the base object will be reflected in all instances.
|
|
||||||
"""
|
|
||||||
instance = copy.deepcopy(self)
|
|
||||||
instance.wrapped.TShape(self.wrapped.TShape())
|
|
||||||
return instance
|
|
||||||
|
|
||||||
def transform_shape(self, t_matrix: Matrix) -> Shape:
|
def transform_shape(self, t_matrix: Matrix) -> Shape:
|
||||||
"""Apply affine transform without changing type
|
"""Apply affine transform without changing type
|
||||||
|
|
||||||
|
|
@ -6755,9 +6753,8 @@ class Vertex(Shape):
|
||||||
Example:
|
Example:
|
||||||
part.faces(">z").vertices("<y and <x").val() + (0, 0, 15)
|
part.faces(">z").vertices("<y and <x").val() + (0, 0, 15)
|
||||||
|
|
||||||
which creates a new Vertex 15mm above one extracted from a part. One can add or
|
which creates a new Vertex 15 above one extracted from a part. One can add or
|
||||||
subtract a cadquery `Vertex` , `Vector` or `tuple` of float values to a
|
subtract a `Vertex` , `Vector` or `tuple` of float values to a Vertex.
|
||||||
Vertex with the provided extensions.
|
|
||||||
"""
|
"""
|
||||||
if isinstance(other, Vertex):
|
if isinstance(other, Vertex):
|
||||||
new_vertex = Vertex(self.X + other.X, self.Y + other.Y, self.Z + other.Z)
|
new_vertex = Vertex(self.X + other.X, self.Y + other.Y, self.Z + other.Z)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue