Skip to content

Commit

Permalink
FEAT: Added chamfers and fillet methods to Object3d (#4763)
Browse files Browse the repository at this point in the history
Co-authored-by: maxcapodi78 <Shark78>
Co-authored-by: Maxime Rey <[email protected]>
  • Loading branch information
maxcapodi78 and MaxJPRey authored Jun 5, 2024
1 parent 5ca09d2 commit d721cd1
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 9 deletions.
7 changes: 6 additions & 1 deletion _unittest/test_07_Object3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,13 @@ def test_10_chamfer(self):
assert test
test = initial_object.edges[4].chamfer(chamfer_type=4)
assert not test

self.aedtapp.modeler.delete(initial_object)
initial_object = self.aedtapp.modeler.create_box([0, 0, 0], [10, 10, 5], "ChamferTest2", "Copper")
assert initial_object.chamfer(edges=initial_object.faces[0].edges[0], chamfer_type=3)
initial_object = self.aedtapp.modeler.create_box([0, 0, 0], [10, 10, 5], "ChamferTest3", "Copper")
assert initial_object.chamfer(edges=initial_object.faces[0].edges[0], chamfer_type=1)
initial_object = self.aedtapp.modeler.create_box([0, 0, 0], [10, 10, 5], "ChamferTest4", "Copper")
assert initial_object.chamfer(edges=initial_object.faces[2].edges[0], chamfer_type=2)

def test_11_fillet(self):
initial_object = self.aedtapp.modeler.create_box([0, 0, 0], [10, 10, 5], "FilletTest", "Copper")
Expand Down
4 changes: 4 additions & 0 deletions _unittest/test_08_Primitives3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,8 @@ def test_42_chamfer(self):
assert o.edges[0].chamfer(chamfer_type=3)
self.aedtapp._odesign.Undo()
assert not o.edges[0].chamfer(chamfer_type=4)
o2 = self.create_copper_box(name="MyBox2")
assert o2.chamfer(edges=o2.edges)

def test_43_fillet_and_undo(self):
o = self.create_copper_box(name="MyBox")
Expand All @@ -701,6 +703,8 @@ def test_43_fillet_and_undo(self):
assert o.edges[0].fillet()
r = self.create_rectangle(name="MyRect")
assert not r.edges[0].fillet()
o2 = self.create_copper_box(name="MyBox2")
assert o2.fillet(edges=o2.edges)

def test_44_create_polyline_basic_segments(self):
prim3D = self.aedtapp.modeler
Expand Down
9 changes: 8 additions & 1 deletion _unittest/test_09_Primitives2D.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,18 @@ def test_05_create_poly(self):

def test_chamfer_vertex(self):
o = self.create_rectangle("Rectangle1")
o.vertices[0].chamfer()
assert o.vertices[0].chamfer()
o2 = self.create_rectangle("Rectangle2")
assert o2.chamfer(o2.vertices)
assert not o2.chamfer(edges=o2.edges)
assert not o2.chamfer()

def test_fillet_vertex(self):
o = self.create_rectangle("Rectangle1")
o.vertices[0].fillet()
o2 = self.create_rectangle("Rectangle2")
assert o2.fillet(o2.vertices)
assert not o2.fillet(edges=o2.edges)

def test_06_create_region(self):
if self.aedtapp.modeler["Region"]:
Expand Down
2 changes: 1 addition & 1 deletion _unittest/test_14_AedtLogger.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def test_log_when_accessing_non_existing_object(self, caplog):
)
with pytest.raises(AttributeError):
app.get_object_material_properties("MS1", "conductivity")
assert ("Global", logging.ERROR, "Object 'MS1' not found.") in caplog.record_tuples
assert ("Global", logging.ERROR, " assignment = MS1 ") in caplog.record_tuples


class CaptureStdOut:
Expand Down
20 changes: 14 additions & 6 deletions pyaedt/modeler/cad/Primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ def __setitem__(self, key, value):
if self.__obj_type == "o":
self.__parent._object_names_to_ids[value.name] = key

@pyaedt_function_handler()
def __getitem__(self, item):
if item in dict.keys(self):
return dict.__getitem__(self, item)
Expand Down Expand Up @@ -208,11 +207,20 @@ def __getitem__(self, partId):
return partId
try:
return self.objects[partId]
except Exception:
if partId in self.user_defined_components.keys():
return self.user_defined_components[partId]
self.logger.error("Object '{}' not found.".format(partId))
return None
except KeyError:
pass
try:
return self.user_defined_components[partId]
except KeyError:
pass
try:
return self.planes[partId]
except KeyError:
pass
try:
return self.points[partId]
except KeyError:
return

def __init__(self, app, is3d=True):
self._app = app
Expand Down
124 changes: 124 additions & 0 deletions pyaedt/modeler/cad/object3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -1914,3 +1914,127 @@ def _change_property(self, vPropChange):

def __str__(self):
return self.name

@pyaedt_function_handler()
def fillet(self, vertices=None, edges=None, radius=0.1, setback=0.0):
"""Add a fillet to the selected edges in 3D/vertices in 2D.
Parameters
----------
vertices : list, optional
List of vertices to fillet. Default is ``None``.
edges : list, optional
List of edges to fillet. Default is ``None``.
radius : float, optional
Radius of the fillet. The default is ``0.1``.
setback : float, optional
Setback value for the file. The default is ``0.0``.
Returns
-------
bool
``True`` when successful, ``False`` when failed.
References
----------
>>> oEditor.Fillet
"""
if not vertices and not edges:
self.logger.error("Either vertices or edges have to be provided as input.")
return False
edge_id_list = []
vertex_id_list = []
if edges is not None:
edge_id_list = self._primitives.convert_to_selections(edges, return_list=True)
if vertices is not None:
vertex_id_list = self._primitives.convert_to_selections(vertices, return_list=True)

vArg1 = ["NAME:Selections", "Selections:=", self.name, "NewPartsModelFlag:=", "Model"]
vArg2 = ["NAME:FilletParameters"]
vArg2.append("Edges:="), vArg2.append(edge_id_list)
vArg2.append("Vertices:="), vArg2.append(vertex_id_list)
vArg2.append("Radius:="), vArg2.append(self._primitives._arg_with_dim(radius))
vArg2.append("Setback:="), vArg2.append(self._primitives._arg_with_dim(setback))
self._oeditor.Fillet(vArg1, ["NAME:Parameters", vArg2])
if self.name in list(self._oeditor.GetObjectsInGroup("UnClassified")):
self._primitives._odesign.Undo()
self.logger.error("Operation failed, generating an unclassified object. Check and retry.")
return False
return True

@pyaedt_function_handler()
def chamfer(self, vertices=None, edges=None, left_distance=1, right_distance=None, angle=45, chamfer_type=0):
"""Add a chamfer to the selected edges in 3D/vertices in 2D.
Parameters
----------
vertices : list, optional
List of vertices to chamfer.
edges : list, optional
List of edges to chamfer.
left_distance : float, optional
Left distance from the edge. The default is ``1``.
right_distance : float, optional
Right distance from the edge. The default is ``None``.
angle : float, optional.
Angle value for chamfer types 2 and 3. The default is ``0``.
chamfer_type : int, optional
Type of the chamfer. Options are:
* 0 - Symmetric
* 1 - Left Distance-Right Distance
* 2 - Left Distance-Angle
* 3 - Right Distance-Angle
The default is ``0``.
Returns
-------
bool
``True`` when successful, ``False`` when failed.
References
----------
>>> oEditor.Chamfer
"""
edge_id_list = []
vertex_id_list = []
if edges is not None:
edge_id_list = self._primitives.convert_to_selections(edges, return_list=True)
if vertices is not None:
vertex_id_list = self._primitives.convert_to_selections(vertices, return_list=True)
if vertex_id_list == edge_id_list == []:
self.logger.error("Vertices or Edges have to be provided as input.")
return False
vArg1 = ["NAME:Selections", "Selections:=", self.name, "NewPartsModelFlag:=", "Model"]
vArg2 = ["NAME:ChamferParameters"]
vArg2.append("Edges:="), vArg2.append(edge_id_list)
vArg2.append("Vertices:="), vArg2.append(vertex_id_list)
vArg2.append("LeftDistance:="), vArg2.append(self._primitives._arg_with_dim(left_distance))
if not right_distance:
right_distance = left_distance
if chamfer_type == 0:
vArg2.append("RightDistance:="), vArg2.append(self._primitives._arg_with_dim(right_distance))
vArg2.append("ChamferType:="), vArg2.append("Symmetric")
elif chamfer_type == 1:
vArg2.append("RightDistance:="), vArg2.append(self._primitives._arg_with_dim(right_distance))
vArg2.append("ChamferType:="), vArg2.append("Left Distance-Right Distance")
elif chamfer_type == 2:
vArg2.append("Angle:="), vArg2.append(str(angle) + "deg")
vArg2.append("ChamferType:="), vArg2.append("Left Distance-Right Distance")
elif chamfer_type == 3:
vArg2.append("LeftDistance:="), vArg2.append(str(angle) + "deg")
vArg2.append("RightDistance:="), vArg2.append(self._primitives._arg_with_dim(right_distance))
vArg2.append("ChamferType:="), vArg2.append("Right Distance-Angle")
else:
self.logger.error("Wrong Type Entered. Type must be integer from 0 to 3")
return False
self._oeditor.Chamfer(vArg1, ["NAME:Parameters", vArg2])
if self.name in list(self._oeditor.GetObjectsInGroup("UnClassified")):
self._primitives._odesign.Undo()
self.logger.error("Operation Failed generating Unclassified object. Check and retry")
return False
return True

0 comments on commit d721cd1

Please sign in to comment.