Skip to content

Commit

Permalink
WIP: working on solving tenon-mortise
Browse files Browse the repository at this point in the history
  • Loading branch information
9and3 committed Apr 9, 2024
1 parent 50b2786 commit d8eefa6
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 287 deletions.
2 changes: 1 addition & 1 deletion src/gh/diffCheck/diffCheck/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.0.2'
__version__ = '0.0.3'
80 changes: 75 additions & 5 deletions src/gh/diffCheck/diffCheck/df_geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,23 @@ def __post_init__(self):
def __repr__(self):
return f"Vertex: X={self.x}, Y={self.y}, Z={self.z}"

def from_rg_point3d(point: rg.Point3d):
return DFVertex(point.X, point.Y, point.Z)
def __hash__(self):
return hash((self.x, self.y, self.z))

def __eq__(self, other):
if isinstance(other, DFVertex):
return self.x == other.x and self.y == other.y and self.z == other.z
return False

@classmethod
def from_rg_point3d(cls, point: rg.Point3d):
"""
Create a DFVertex from a Rhino Point3d object
:param point: The Rhino Point3d object
:return vertex: The DFVertex object
"""
return cls(point.X, point.Y, point.Z)


@dataclass
Expand All @@ -45,13 +60,21 @@ def __post_init__(self):
raise ValueError("A face must have at least 3 vertices")
self.vertices = self.vertices or []

self.joint_id = self.joint_id or None
self.joint_id = self.joint_id
self.__is_joint = False
self.__id = uuid.uuid4().int

def __repr__(self):
return f"Face vertices: {len(self.vertices)}"

def __hash__(self):
return hash((tuple(self.vertices), self.joint_id))

def __eq__(self, other):
if isinstance(other, DFFace):
return self.vertices == other.vertices and self.joint_id == other.joint_id
return False

@staticmethod
def compute_mass_center(face: rg.BrepFace) -> rg.Point3d:
"""
Expand All @@ -65,9 +88,44 @@ def compute_mass_center(face: rg.BrepFace) -> rg.Point3d:
return amp.Centroid
return None

@classmethod
def from_brep(cls, brep_face: rg.BrepFace, joint_id: int=None):
"""
Create a DFFace from a Rhino Brep face
:param brep_face: The Rhino Brep face
:param joint_id: The joint id
:return face: The DFFace object
"""
vertices = []
face_loop = brep_face.OuterLoop
face_loop_trims = face_loop.Trims

face_curve_loop = brep_face.OuterLoop.To3dCurve()
face_curve_loop = face_curve_loop.ToNurbsCurve()
face_vertices = face_curve_loop.Points

for f_v in face_vertices:
vertex = DFVertex(f_v.X, f_v.Y, f_v.Z)
vertices.append(vertex)

return cls(vertices, joint_id)

def to_brep(self):
"""
Convert the face to a Rhino Brep planar face
:return brep_face: The Rhino Brep planar face
"""
vertices : rg.Point3d = [rg.Point3d(vertex.x, vertex.y, vertex.z) for vertex in self.vertices]
polyline = rg.Polyline(vertices)
face_brep = rg.Brep.CreatePlanarBreps([polyline.ToNurbsCurve()])[0]

return face_brep

@property
def is_joint(self):
if self.joint_id:
if self.joint_id is not None:
self.__is_joint = True
return True
self.__is_joint = False
Expand All @@ -88,15 +146,19 @@ class DFBeam:
def __post_init__(self):
self.name = self.name or "Unnamed Beam"
self.faces = self.faces or []
self._joint_faces = []
self._side_faces = []

self.__id = uuid.uuid4().int

@classmethod
def from_brep(cls, brep):
"""
Create a DFBeam from a RhinoBrep object
Create a DFBeam from a RhinoBrep object.
It also removes duplicates and creates a list of unique faces.
"""
faces = JointDetector(brep).run()
faces = list(set(faces))
beam = cls("Beam", faces)
return beam

Expand All @@ -107,6 +169,14 @@ def __repr__(self):
def id(self):
return self.__id

@property
def joint_faces(self):
return [face for face in self.faces if face.is_joint]

@property
def side_faces(self):
return [face for face in self.faces if not face.is_joint]


@dataclass
class DFAssembly:
Expand Down
32 changes: 14 additions & 18 deletions src/gh/diffCheck/diffCheck/df_joint_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,14 @@ def run(self) -> typing.List[DFFace]:
b.Transform(x_form_back)
for b in self._cuts:
b.Transform(x_form_back)
for b in self._mix:
b.Transform(x_form_back)
self.brep.Transform(x_form_back)

# get all the medians of the faces of cuts only
cuts_faces_centroids : typing.Dict[int, typing.List[rg.Point3d]] = {}

# get all the medians of the faces of cuts
for idx, b in enumerate(self._cuts):
idx = idx + 1
temp_face_centroids = []
for f in b.Faces:
centroid = DFFace.compute_mass_center(f)
Expand All @@ -170,22 +172,16 @@ def run(self) -> typing.List[DFFace]:
# compare with the brep medians faces to get the joint/sides's faces
for f in self.brep.Faces:
centroid_2test = DFFace.compute_mass_center(f)
for idx, centroids in cuts_faces_centroids.items():
for key, centroids in cuts_faces_centroids.items():
is_joint = False
for centroid in centroids:
if centroid_2test.DistanceTo(centroid) < sc.doc.ModelAbsoluteTolerance:
df_vertices = []
face_loop = f.OuterLoop
face_loop_trims = face_loop.Trims
for face_loop_trim in face_loop_trims:
df_vertices.append(DFVertex.from_rg_point3d(face_loop_trim.PointAtStart))
self._faces.append(DFFace(df_vertices, idx))
self._faces.append(DFFace.from_brep(f, key))
is_joint = True
break
else:
df_vertices = []
face_loop = f.OuterLoop
face_loop_trims = face_loop.Trims
for face_loop_trim in face_loop_trims:
df_vertices.append(DFVertex.from_rg_point3d(face_loop_trim.PointAtStart))
self._faces.append(DFFace(df_vertices))

return self._faces
if is_joint:
break
if not is_joint:
self._faces.append(DFFace.from_brep(f, None))

return self._faces
13 changes: 12 additions & 1 deletion src/gh/diffCheck/diffCheck/diffCheck_app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#! python3

import Rhino
import Rhino.Geometry as rg
import scriptcontext as sc
Expand Down Expand Up @@ -35,4 +36,14 @@
xml : str = assembly1.to_xml()
if i_dump:
assembly1.dump(xml, i_export_dir)
o_xml = xml
o_xml = xml

# show the joint/side faces
joints_faces_breps = []
sides_faces_breps = []
for beam in beams:
joints_faces_breps.extend([face.to_brep() for face in beam.joint_faces])
sides_faces_breps.extend([face.to_brep() for face in beam.side_faces])

o_joints = joints_faces_breps
o_sides = sides_faces_breps
2 changes: 1 addition & 1 deletion src/gh/diffCheck/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='diffCheck',
version='0.0.2',
version='0.0.3',
packages=find_packages(),
description='DiffCheck is a package to check the differences between two timber structures',
long_description=open('README.md').read(),
Expand Down
Loading

0 comments on commit d8eefa6

Please sign in to comment.