compas_tf.base_model
¤
A local copy of compas_model.models.model.
compas_tf inherits from this instead of :class:compas_model.models.Model
because the Model compas_tf needs does not exist in any compas_model release.
duplicate, merge, compute_contacts_between_groups and
find_group_with_name live only on an unmerged branch - verified by reading
compas_model/models/model.py out of the published 0.9.3 wheel, where all
four are absent. Depending on that branch meant compas_tf only worked against a
local editable checkout.
Everything this module imports FROM compas_model (Element, Group, Contact, Material, Modifier, KDTree, ElementTree, ElementNode, InteractionGraph, the BVH node types) does ship in 0.9.3, so only the model class itself is copied.
Kept as a verbatim copy rather than a patch so it can be diffed against
upstream. :class:compas_tf.model.TFModel subclasses it. Delete this module and
go back to inheriting from compas_model once that branch is released.
find_groups_with_names is the one method here that is compas_tf's own rather
than the branch's, and belongs upstream with the other four.
Classes¤
BaseModel
¤
Class representing a general model of hierarchically organised elements, with interactions.
Notes
A model has an element tree to store the hierarchical relationships between elements, and an interaction graph to store the interactions between pairs of elements. BaseModel elements are contained in the tree hierarchy in tree nodes, and in the interaction graph in graph nodes.
Every model element can appear only once in the tree, and only once in the graph. This means that every element can have only one hierarchical parent. At the same time, independently of the hierarchy, every element can have many interactions with other elements.
-
API Reference
base_model ClassesBaseModel Methods:
- API Reference
Methods:¤
add_element
¤
add_element(element: Element | ElementType, parent: Element | None = None, material: Material | None = None) -> Element | ElementType
Add an element to the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element
|
Element | ElementType
|
The element to add. |
required |
parent
|
Element | None
|
The parent element of the element.
If |
None
|
material
|
Material | None
|
A material to assign to the element. Note that the material should have already been added to the model before it can be assigned. |
None
|
Returns:
| Type | Description |
|---|---|
Element
|
The element added to the model. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the parent node is not a GroupNode. |
ValueError
|
If a material is provided that is not part of the model. |
add_elements
¤
add_elements(elements: list[Element | ElementType], parent: Element | None = None, material: Material | None = None) -> list[Element | ElementType]
Add a list of elements to the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
elements
|
list[Element | ElementType]
|
The elements to add. |
required |
parent
|
Element | None
|
The parent element of the elements.
If |
None
|
material
|
Material | None
|
A material to assign to the elements. Note that the material should have already been added to the model before it can be assigned. |
None
|
Returns:
| Type | Description |
|---|---|
list[Element]
|
The list of elements added to the model. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the parent node is not a GroupNode. |
ValueError
|
If a material is provided that is not part of the model. |
add_group
¤
add_group(name: str | None = None) -> Group
Add a group to the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
The name of the group. |
None
|
Returns:
| Type | Description |
|---|---|
Group
|
The group added to the model. |
add_interaction
¤
Add an interaction between two elements of the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a
|
Element
|
The first element. |
required |
b
|
Element
|
The second element. |
required |
Returns:
| Type | Description |
|---|---|
tuple[int, int]
|
The edge of the interaction graph representing the interaction between the two elements. |
Raises:
| Type | Description |
|---|---|
Exception
|
If one or both of the elements are not in the graph. |
Notes
In future implementations, adding an interaction should implicitly take care of adding modifiers onto the interaction edges, based on the registered modifiers of the source nodes.
In the current implementation, modifiers have to be added explicitly using :meth:add_modifiers.
This method will add an interaction edge from the source of the modifier to its target if needed
and store the modifier object on it.
add_material
¤
Add a material to the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
material
|
Material
|
A material. |
required |
add_modifier
¤
add_modifier(source: Element, target: Element, modifier: Modifier) -> list[Modifier]
Add a modifier between two elements, with one the source of the modifier and the other the target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Element
|
The source element. |
required |
target
|
Element
|
The target element. |
required |
modifier
|
Modifier
|
The modifier. |
required |
Returns:
| Type | Description |
|---|---|
list[Modifier]
|
All modifiers stored on the interaction edge between source and target. |
Notes
This element should implement the protocol specified by the modifier. The methods of the source element defined by the protocol are used to compute the tools involved in the modification. The tools are used by the modifier to apply the modification to the model geometry of the target element.
The modifier defines the protocol for the modification. The protocol should be implemented by the source element. The protocol methods of the source element are used to compute the modification tool. The modifier applies the modification to the target using this tool.
add_or_get_material
¤
Add a material to the model or retrieve an existing instance of the same type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
material
|
Material
|
A material. |
required |
Returns:
| Type | Description |
|---|---|
Material
|
The added or existing material. |
assign_material
¤
assign_material(material: Material, element: Element | None = None, elements: list[Element] | None = None) -> None
Assign a material to an element or a list of elements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
material
|
Material
|
The material. |
required |
element
|
Element | None
|
The element to assign the material to. |
None
|
elements
|
list[Element] | None
|
The list of elements to assign the material to. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither |
ValueError
|
If both |
ValueError
|
If the material is not part of the model. |
ValueError
|
If the provided element or one of the elements in the provided element list is not part of the model. |
compute_bvh
¤
compute_bvh(nodetype: type[ElementAABBNode] | type[ElementOBBNode] = ElementAABBNode, max_depth: int | None = None, leafsize: int = 1) -> ElementBVH
Compute the Bounding Volume Hierarchy (BVH) of the elements for fast collision checks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodetype
|
type[ElementAABBNode] | type[ElementOBBNode]
|
The type of bounding volume node used in the tree. |
ElementAABBNode
|
max_depth
|
int | None
|
The maximum depth used for constructing the BVH. |
None
|
leafsize
|
int
|
The number of elements contained in a BVH leaf node. |
1
|
Returns:
| Type | Description |
|---|---|
ElementBVH
|
The computed BVH. |
compute_contacts
¤
compute_contacts(tolerance: float = 1e-06, minimum_area: float = 0.01, contacttype: type[Contact] = Contact) -> None
Compute the contacts between the block elements of this model.
Computing contacts is done independently of the edges of the interaction graph. If contacts are found between two elements with an existing edge, the contacts attribute of the edge will be replaced. If there is no pre-existing edge, one will be added. No element pairs are excluded in the search based on the existence of an edge between their nodes in the interaction graph.
The search is conducted entirely based on the BVH of the elements contained in the model. It is a spatial search that creates topological connections between elements based on their geometrical interaction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tolerance
|
float
|
The distance tolerance. |
1e-06
|
minimum_area
|
float
|
The minimum contact size. |
0.01
|
contacttype
|
type[Contact]
|
The contact class to use for the generated contacts. |
Contact
|
compute_contacts_between_groups
¤
compute_contacts_between_groups(groups: list[str], groups_b: list[str] | None = None, tolerance: float = 1e-06, minimum_area: float = 0.01, contacttype: type[Contact] = Contact, contactmethod: Callable | None = None) -> None
Compute contacts only between elements of different named groups.
Like :meth:compute_contacts, this is a spatial (BVH) search that adds
a contact interaction wherever two element geometries touch. Unlike it,
only the named groups take part, and pairs within a single group are
never tested.
Two modes:
-
All-pairs (
groups_bomitted): detection runs between every unordered pair of distinct groups ingroups. This is the natural companion to :meth:merge- every merged sub-model becomes its own group, so passing those names finds the seams between the sub-models. -
Two-sided (
groups_bgiven): detection runs only between an element of agroupsgroup and an element of agroups_bgroup. Pairs withingroupsand pairs withingroups_bare skipped. Use this to contact one set against another - e.g. columns against only the outer ribs - without the ribs also contacting each other.
Each element is assigned to the nearest enclosing group whose name is requested, so nested groups behave predictably: pass an outer group name to treat all its descendants as one group, or the inner names to keep them apart.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
groups
|
list[str]
|
Names of the groups on the first side. |
required |
groups_b
|
list[str] | None
|
Names of the groups on the second side. If |
None
|
tolerance
|
float
|
The distance tolerance. |
1e-06
|
minimum_area
|
float
|
The minimum contact size. |
0.01
|
contacttype
|
type[Contact]
|
The contact class to use for the generated contacts. |
Contact
|
contactmethod
|
Callable | None
|
What actually detects the contacts of one accepted pair, called as
|
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
All-pairs: if fewer than two named groups contain any elements. Two-sided: if either side has no elements. |
compute_kdtree
¤
Compute the KD tree of the elements for fast nearest neighbour queries.
The KD tree is built using the reference points of the elements of the model.
Returns:
| Type | Description |
|---|---|
KDTree
|
The computed KD tree. |
duplicate
¤
duplicate() -> BaseModel
Return a fully independent copy of this model (elements get new guids).
Unlike :meth:copy (and deepcopy), which reproduce each element's
guid verbatim - so two copies share guids and cannot coexist in one
model - duplicate re-clones every element with a fresh guid and
rewires the tree/graph. The result is independent, so it can be placed
and :meth:merge-d alongside the original.
Returns:
| Type | Description |
|---|---|
BaseModel
|
An independent copy of this model. |
element_nnbrs
¤
Find the nearest neighbours to a root element.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element
|
Element
|
The root element. |
required |
k
|
int
|
The number of nearest neighbours that should be returned. |
1
|
Returns:
| Type | Description |
|---|---|
list[tuple[Element, float]]
|
A list of nearest neighbours, with each neighbour defined as an element and the distance of that element to the root element. |
elements
¤
elements() -> Iterator[Element]
Iterate over the elements contained in the model.
Returns:
| Type | Description |
|---|---|
Iterator[Element]
|
The elements contained in the model. |
find_all_elements_of_type
¤
find_element_with_name
¤
find_element_with_name(name: str) -> Element | None
Returns True if the model contains an element with the given name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name to check. |
required |
Returns:
| Type | Description |
|---|---|
Element or None
|
The element with the name, if found. |
find_group_with_name
¤
Extract a named group's subtree as a new, independent model.
Search the element tree for a :class:Group with the given name and
return a fresh model holding an independent copy of that group's
contents - its elements re-cloned with new guids (like
:meth:duplicate), their hierarchy preserved, and any interactions
(with their modifiers/contacts) that fall entirely within the subtree
carried along. The source model is left untouched.
This is the inverse of :meth:merge: merge nests a model under a
group named after it, while find_group_with_name lifts such a group
back out into a standalone model (named after the group). The group's
full placement in the source hierarchy - the accumulated transformation
of its ancestors and the source model itself - is baked into the new
model's transformation, so the extracted geometry keeps its world
position. The first group matching the name is used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the group to extract. |
required |
Returns:
| Type | Description |
|---|---|
BaseModel or None
|
A new model rooted at the group's contents, or |
find_groups_with_names
¤
find_groups_with_names(names: list[str], name: str | None = None, neighbors: bool | tuple | Callable = False) -> BaseModel
Extract several named groups at once, as one new independent model.
The multi-group counterpart of :meth:find_group_with_name, for lifting
an assembly out of a big model - one column plus the quarter it carries,
say. Because the groups are extracted together, the interactions BETWEEN
them survive; extracting them one at a time and merging the results
would lose exactly those, which is the joint you wanted.
Where :meth:find_group_with_name drops the group node and folds its
placement into the new model's transformation, this keeps each group's
chain of ancestors - pruned to the groups asked for. So a
quarter_model_0 under floor_model/quarters_model comes back at
the same path, and every group transformation on the way down still
applies. The elements are re-cloned with fresh guids and the source
model is left untouched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
names
|
list[str]
|
The names of the groups to extract. The first group matching each name is used. |
required |
name
|
str | None
|
Name for the new model. Defaults to the names joined by |
None
|
neighbors
|
bool | tuple | Callable
|
Also bring in elements outside the named groups that belong with one
inside - the loose fasteners a bay is bolted together with, which
live in their own top-level group rather than in the bay's. Two
passes: every element that interacts with one inside, and then, for
the elements that have no interaction at all, every one whose
bounding box lands inside the bay. Their ancestor groups are
recreated the same way. The second pass reads
|
False
|
Returns:
| Type | Description |
|---|---|
BaseModel
|
A new model holding an independent copy of those groups. |
Raises:
| Type | Description |
|---|---|
ModelElementNotFound
|
If any of the names does not match a group. |
has_element
¤
has_element(element: Element) -> bool
Returns True if the model contains the given element.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element
|
Element
|
The element to check. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the model contains the element. |
has_element_with_name
¤
has_interaction
¤
has_interaction(a: Element, b: Element) -> bool
Returns True if two elements have an interaction set between them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a
|
Element
|
The first element. |
required |
b
|
Element
|
The second element. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the elements have an interaction. |
has_material
¤
has_material(material: Material) -> bool
Verify that the model contains a specific material.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
material
|
Material
|
A model material. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the model contains the material. |
materials
¤
materials() -> Iterator[Material]
Iterate over the materials stored in the model.
Returns:
| Type | Description |
|---|---|
Iterator[Material]
|
The materials stored in the model. |
merge
¤
Merge a list of models into this model, each under its own group.
Each input is added under a new group (named after it) nested under
parent - or under the model root when parent is None. For
every input its materials, element tree (hierarchy preserved) and
interactions (with their modifiers/contacts) are brought in. The inputs
are consumed - their elements are moved in, not copied - so
:meth:duplicate them first if you need to keep the originals (or to
merge several instances of one model).
Build a new combined model by merging into a fresh one, optionally in one
line: BaseModel(name="columns").merge(column_models). Insert into an
existing model under a chosen group/element by passing parent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
models
|
list[BaseModel]
|
The list of models to merge into this one. |
required |
parent
|
Element | None
|
The group/element to nest the merged models under. Root if |
None
|
Returns:
| Type | Description |
|---|---|
BaseModel
|
This model (returned for chaining). |
point_nnbrs
¤
Find the nearest neighbours to a point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
point
|
Point
|
The root point. |
required |
k
|
int
|
The number of nearest neighbours that should be returned. |
1
|
Returns:
| Type | Description |
|---|---|
list[tuple[Element, float]]
|
A list of nearest neighbours, with each neighbour defined as an element and the distance of that element to the root element. |
remove_element
¤
Remove an element from the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element
|
Element
|
The element to remove. |
required |
remove_elements_of_type
¤
remove_interaction
¤
Remove the interaction between two elements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a
|
Element
|
|
required |
b
|
Element
|
|
required |
transform
¤
transform(transformation: Transformation) -> None
Transform the model and all that it contains.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
transformation
|
Transformation
|
The transformation to apply. |
required |