Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `compas_model.elements.FastenersElement`.
* Added `compas_model.elements.ScrewElement`.
* Added `Element.is_dirty`.
* Added `compas_model.models.BlockModel.from_barrel_vault`.
* Added `compas_model.elements.BeamTProfileElement`.


### Changed

Expand Down
1 change: 1 addition & 0 deletions data/frame.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Model::Line::Segments": [{"dtype": "compas.geometry/Line", "data": {"start": [-3000.0, -3000.0, 0.0], "end": [-3000.0, -3000.0, 3800.0]}, "guid": "cf28f7ab-9674-46d2-bcf8-11677a4dfc3c"}, {"dtype": "compas.geometry/Line", "data": {"start": [-3000.0, 3000.0, 0.0], "end": [-3000.0, 3000.0, 3800.0]}, "guid": "e748b58d-50cf-47da-ac7c-696cecd38c3c"}, {"dtype": "compas.geometry/Line", "data": {"start": [3000.0, 3000.0, 0.0], "end": [3000.0, 3000.0, 3800.0]}, "guid": "b861dcd1-ac54-4777-954b-fc07f5446f54"}, {"dtype": "compas.geometry/Line", "data": {"start": [3000.0, -3000.0, 0.0], "end": [3000.0, -3000.0, 3800.0]}, "guid": "91d8c7f1-d691-4fe7-8eea-a77b0f09aa78"}, {"dtype": "compas.geometry/Line", "data": {"start": [-3000.0, -3000.0, 3800.0], "end": [-3000.0, 3000.0, 3800.0]}, "guid": "b36ddcaa-b602-4e13-964d-f7938a1095a7"}, {"dtype": "compas.geometry/Line", "data": {"start": [3000.0, 3000.0, 3800.0], "end": [3000.0, -3000.0, 3800.0]}, "guid": "07ba1c41-4a7a-468e-8ba2-ef933dd39063"}, {"dtype": "compas.geometry/Line", "data": {"start": [-3000.0, 3000.0, 3800.0], "end": [3000.0, 3000.0, 3800.0]}, "guid": "7c70770f-da40-4456-9d60-195a56aa7021"}, {"dtype": "compas.geometry/Line", "data": {"start": [3000.0, -3000.0, 3800.0], "end": [-3000.0, -3000.0, 3800.0]}, "guid": "e2192a46-5b59-45f9-88a3-70eefc706cd0"}], "Model::Mesh::Floor": [{"dtype": "compas.datastructures/Mesh", "data": {"attributes": {}, "default_vertex_attributes": {"x": 0.0, "y": 0.0, "z": 0.0}, "default_edge_attributes": {}, "default_face_attributes": {}, "vertex": {"0": {"x": -3000.0, "y": -3000.0, "z": 3800.0}, "1": {"x": -3000.0, "y": 3000.0, "z": 3800.0}, "2": {"x": 3000.0, "y": 3000.0, "z": 3800.0}, "3": {"x": 3000.0, "y": -3000.0, "z": 3800.0}}, "face": {"0": [0, 1, 2, 3]}, "facedata": {"0": {}}, "edgedata": {}, "max_vertex": 3, "max_face": 0}, "guid": "ca32458c-6b40-4074-837a-32acb1d87e41"}]}
5 changes: 1 addition & 4 deletions docs/api/compas_model.elements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,5 @@ Classes
:toctree: generated/
:nosignatures:

BlockElement
BlockFeature
BlockGeometry
Element
Feature

46 changes: 46 additions & 0 deletions docs/examples/contacts/boolean_modifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from math import pi

from compas.geometry.rotation import Rotation
from compas.geometry.translation import Translation
from compas.tolerance import TOL
from compas_model.elements import BeamSquareElement
from compas_model.models import Model
from compas_viewer import Viewer
from compas_viewer.config import Config

# =============================================================================
# Model
# =============================================================================

model = Model()

beam0: BeamSquareElement = BeamSquareElement(
width=0.2,
depth=0.3,
length=6,
)

beam1: BeamSquareElement = BeamSquareElement(
width=0.2,
depth=0.3,
length=6,
)

beam_node = model.add_element(beam0)
model.add_element(beam1, parent=beam_node)
rotation: Rotation = Rotation.from_axis_and_angle([0, 1, 0], pi / 4, point=beam1.axis.midpoint)
translation = Translation.from_vector([0, 0.1, 0])
beam1.transformation = translation * rotation

model.compute_contact(beam0, beam1) # this method works when Beam class has modifier method

# =============================================================================
# Vizualize
# =============================================================================
TOL.lineardeflection = 1000

config = Config()
viewer = Viewer(config=config)
for element in model.elements():
viewer.scene.add(element.modelgeometry)
viewer.show()
48 changes: 48 additions & 0 deletions docs/examples/contacts/contact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from pathlib import Path

from compas import json_load
from compas.datastructures import Mesh
from compas.geometry import Line
from compas.geometry import Polygon
from compas.tolerance import TOL
from compas_model.elements import ColumnHeadCrossElement
from compas_model.elements import PlateElement
from compas_model.models import Model
from compas_viewer import Viewer
from compas_viewer.config import Config

# =============================================================================
# Model
# =============================================================================
model: Model = Model()

# =============================================================================
# Add Elements to CellNetwork Edge
# =============================================================================


column_head = ColumnHeadCrossElement(width=0.150, depth=0.150, height=0.300, offset=0.210)
plate: PlateElement = PlateElement(Polygon([[-2.850, -2.850, 0], [-2.850, 2.850, 0], [2.850, 2.850, 0], [2.850, -2.850, 0]]), 0.200)

model.add_element(column_head)
model.add_element(plate)

# =============================================================================
# Add Interaction
# TODO: Check with other default ColumnHead Planes to Debug compas_occ.
# =============================================================================
model.compute_contact(column_head, plate)

# =============================================================================
# Vizualize
# =============================================================================
TOL.lineardeflection = 1000

config = Config()
viewer = Viewer(config=config)
for element in model.elements():
viewer.scene.add(element.modelgeometry)
# viewer.scene.add(beam1.axis.midpoint)
# viewer.scene.add(beam1.axis)

viewer.show()
28 changes: 28 additions & 0 deletions docs/examples/elements/beam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from compas.tolerance import TOL
from compas_model.elements import BeamTProfileElement
from compas_viewer import Viewer
from compas_viewer.config import Config

scale = 1
beam: BeamTProfileElement = BeamTProfileElement(
width=0.2 * scale,
height=0.3 * scale,
step_height_left=0.1 * scale,
step_height_right=0.1 * scale,
step_width_left=0.05 * scale,
step_width_right=0.05 * scale,
length=6 * scale,
)

TOL.lineardeflection = 1000

config = Config()

config.camera.target = [0, 0.1 * scale, 0]
config.camera.position = [0, -0.2 * scale, 7 * scale]
config.camera.near = 0.1 * scale
config.camera.far = 10 * scale
viewer = Viewer(config=config)
viewer.scene.add(beam.elementgeometry)

viewer.show()
19 changes: 19 additions & 0 deletions docs/examples/elements/column.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from compas_model.elements import ColumnSquareElement
from compas_viewer import Viewer
from compas_viewer.config import Config

scale = 1
column: ColumnSquareElement = ColumnSquareElement()


config = Config()

config.camera.target = [0, 0.1 * scale, 0]
config.camera.position = [0, -0.2 * scale, 7 * scale]
config.camera.near = 0.1 * scale
config.camera.far = 10 * scale
viewer = Viewer(config=config)
viewer.scene.add(column.elementgeometry)
viewer.scene.add(column.axis)

viewer.show()
19 changes: 19 additions & 0 deletions docs/examples/elements/cylinder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from compas_model.elements import CableElement
from compas_viewer import Viewer
from compas_viewer.config import Config

scale = 1
column: CableElement = CableElement()


config = Config()

config.camera.target = [0, 0.1 * scale, 0]
config.camera.position = [0, -0.2 * scale, 7 * scale]
config.camera.near = 0.1 * scale
config.camera.far = 10 * scale
viewer = Viewer(config=config)
viewer.scene.add(column.elementgeometry)
viewer.scene.add(column.axis)

viewer.show()
58 changes: 58 additions & 0 deletions docs/examples/masonry/000_frame.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from pathlib import Path

from compas import json_dump
from compas.datastructures import Mesh
from compas.geometry import Line
from compas.geometry import Point
from compas_viewer import Viewer
from compas_viewer.config import Config

# =============================================================================
# Create Geometry
# =============================================================================

points = [
Point(-3000, -3000, 0),
Point(-3000, 3000, 0),
Point(3000, 3000, 0),
Point(3000, -3000, 0),
Point(-3000, -3000, 3800),
Point(-3000, 3000, 3800),
Point(3000, 3000, 3800),
Point(3000, -3000, 3800),
]

lines = [
Line(points[0], points[0 + 4]),
Line(points[1], points[1 + 4]),
Line(points[2], points[2 + 4]),
Line(points[3], points[3 + 4]),
Line(points[4], points[5]),
Line(points[6], points[7]),
Line(points[5], points[6]),
Line(points[7], points[4]),
]

mesh = Mesh.from_vertices_and_faces(points[4:], [[0, 1, 2, 3]])


# =============================================================================
# Serialize the Frame into a JSON file.
# =============================================================================

model_input: dict[str, list[any]] = {"Model::Line::Segments": lines, "Model::Mesh::Floor": [mesh]}
json_dump(model_input, Path("data/frame.json"))

# =============================================================================
# Vizualize
# =============================================================================

config = Config()
config.camera.target = [0, 0, 100]
config.camera.position = [10000, -10000, 10000]
config.camera.near = 10
config.camera.far = 100000
viewer = Viewer(config=config)
viewer.scene.add(lines)
viewer.scene.add(mesh)
viewer.show()
85 changes: 85 additions & 0 deletions docs/examples/masonry/001_frame_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from pathlib import Path

from compas import json_load
from compas.geometry import Frame
from compas.geometry import Line
from compas.geometry import Translation
from compas.geometry import Vector
from compas.geometry.transformation import Transformation
from compas.tolerance import TOL
from compas_model.elements import BeamTProfileElement
from compas_model.elements import CableElement
from compas_model.elements import ColumnSquareElement
from compas_model.models import BlockModel
from compas_model.models import Model
from compas_viewer import Viewer
from compas_viewer.config import Config

# =============================================================================
# JSON file with the geometry of the model.
# =============================================================================
rhino_geometry: dict[str, list[any]] = json_load(Path("data/frame.json"))
lines: list[Line] = rhino_geometry["Model::Line::Segments"]

# =============================================================================
# Model
# =============================================================================
model = Model()

# Add columns
for i in range(0, 4):
column: ColumnSquareElement = ColumnSquareElement(300, 300, lines[i].length)
column.transformation = Transformation.from_frame_to_frame(Frame.worldXY(), Frame(lines[i].start))
model.add_element(column)


# Add two beams
for i in range(4, len(lines) - 2):
beam: BeamTProfileElement = BeamTProfileElement(width=300, height=700, step_width_left=75, step_height_left=150, length=lines[i].length)
target_frame: Frame = Frame(lines[i].start, Vector.Zaxis().cross(lines[i].vector), Vector.Zaxis())
beam.transformation = Transformation.from_frame_to_frame(Frame.worldXY(), target_frame) * Translation.from_vector([0, beam.height * 0.5, 0])
beam.extend(150)
model.add_element(beam)

# Add two cables
for i in range(6, len(lines)):
cable: CableElement = CableElement(length=lines[i].length, radius=10)
target_frame: Frame = Frame(lines[i].start, Vector.Zaxis().cross(lines[i].vector), Vector.Zaxis())
cable.transformation = Transformation.from_frame_to_frame(Frame.worldXY(), target_frame) * Translation.from_vector([0, beam.height * 0.1, 0])
cable.extend(200)
model.add_element(cable)


# Add blocks, by moving them by the height of the first column.
blockmodel: BlockModel = BlockModel.from_barrel_vault(span=6000, length=6000, thickness=250, rise=600, vou_span=5, vou_length=5)
for block in blockmodel.elements():
block.transformation = Transformation.from_frame_to_frame(Frame.worldXY(), Frame([0, 0, lines[0].end[2]])) * block.transformation
model.add_element(block)


# Add Interactions
for element in list(model.elements()):
if isinstance(element, BeamTProfileElement):
for block in blockmodel.elements():
if isinstance(element, BeamTProfileElement):
model.compute_contact(element, block) # beam -> cuts -> block

for element in list(model.elements()):
if isinstance(element, CableElement):
for beam in list(model.elements()):
if isinstance(beam, BeamTProfileElement):
model.compute_contact(element, beam) # cable -> cuts -> beam

# =============================================================================
# Vizualize
# =============================================================================
TOL.lineardeflection = 100
config = Config()
config.camera.target = [0, 0, 100]
config.camera.position = [10000, -10000, 10000]
config.camera.near = 10
config.camera.far = 100000
viewer = Viewer(config=config)
for element in list(model.elements()):
viewer.scene.add(element.modelgeometry, hide_coplanaredges=False)
viewer.show()
19 changes: 19 additions & 0 deletions docs/examples/masonry/002_block_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from compas.tolerance import TOL
from compas_model.models import BlockModel
from compas_viewer.config import Config
from compas_viewer.viewer import Viewer

model: BlockModel = BlockModel.from_barrel_vault(span=6000, length=6000, thickness=250, rise=600, vou_span=5, vou_length=5)


TOL.lineardeflection = 1000

config = Config()
config.camera.target = [0, 0, 100]
config.camera.position = [10000, -10000, 10000]
config.camera.near = 10
config.camera.far = 100000
viewer = Viewer(config=config)
for element in list(model.elements()):
viewer.scene.add(element.modelgeometry, hide_coplanaredges=True)
viewer.show()
Loading
Loading