|
23 | 23 | IFuse,
|
24 | 24 | IIntersection,
|
25 | 25 | ISphere,
|
| 26 | + IChamfer, |
| 27 | + IFillet, |
26 | 28 | ITorus,
|
27 | 29 | Parts,
|
28 | 30 | ShapeMetadata,
|
@@ -593,29 +595,101 @@ def intersect(
|
593 | 595 | self.set_visible(shape2, False)
|
594 | 596 | return self.add_object(OBJECT_FACTORY.create_object(data, self))
|
595 | 597 |
|
596 |
| - def _get_boolean_operands(self, shape1: str | int | None, shape2: str | int | None): |
597 |
| - objects = self.objects |
| 598 | + def chamfer( |
| 599 | + self, |
| 600 | + name: str = "", |
| 601 | + shape: str | int = None, |
| 602 | + edge: int = 0, |
| 603 | + dist: float = 0.1, |
| 604 | + position: List[float] = [0, 0, 0], |
| 605 | + rotation_axis: List[float] = [0, 0, 1], |
| 606 | + rotation_angle: float = 0, |
| 607 | + ) -> CadDocument: |
| 608 | + """ |
| 609 | + Apply a chamfer operation on an object. |
| 610 | + If no objects are provided as input, the last created object will be used as operand. |
598 | 611 |
|
| 612 | + :param name: The name that will be used for the object in the document. |
| 613 | + :param shape: The input object used for the chamfer. Can be the name of the object or its index in the objects list. |
| 614 | + :param edge: The edge index where to apply chamfer. |
| 615 | + :param dist: The distance of the chamfer. |
| 616 | + :param position: The shape 3D position. |
| 617 | + :param rotation_axis: The 3D axis used for the rotation. |
| 618 | + :param rotation_angle: The shape rotation angle, in degrees. |
| 619 | + :return: The document itself. |
| 620 | + """ # noqa E501 |
| 621 | + shape = self._get_operand(shape) |
| 622 | + |
| 623 | + data = { |
| 624 | + "shape": Parts.Part__Chamfer.value, |
| 625 | + "name": name if name else self._new_name("Chamfer"), |
| 626 | + "parameters": { |
| 627 | + "Base": shape, |
| 628 | + "Edge": edge, |
| 629 | + "Dist": dist, |
| 630 | + "Placement": {"Position": [0, 0, 0], "Axis": [0, 0, 1], "Angle": 0}, |
| 631 | + }, |
| 632 | + } |
| 633 | + self.set_visible(shape, False) |
| 634 | + return self.add_object(OBJECT_FACTORY.create_object(data, self)) |
| 635 | + |
| 636 | + def fillet( |
| 637 | + self, |
| 638 | + name: str = "", |
| 639 | + shape: str | int = None, |
| 640 | + edge: int = 0, |
| 641 | + radius: float = 0.1, |
| 642 | + position: List[float] = [0, 0, 0], |
| 643 | + rotation_axis: List[float] = [0, 0, 1], |
| 644 | + rotation_angle: float = 0, |
| 645 | + ) -> CadDocument: |
| 646 | + """ |
| 647 | + Apply a fillet operation on an object. |
| 648 | + If no objects are provided as input, the last created object will be used as operand. |
| 649 | +
|
| 650 | + :param name: The name that will be used for the object in the document. |
| 651 | + :param shape: The input object used for the fillet. Can be the name of the object or its index in the objects list. |
| 652 | + :param edge: The edge index where to apply fillet. |
| 653 | + :param radius: The radius of the fillet. |
| 654 | + :param position: The shape 3D position. |
| 655 | + :param rotation_axis: The 3D axis used for the rotation. |
| 656 | + :param rotation_angle: The shape rotation angle, in degrees. |
| 657 | + :return: The document itself. |
| 658 | + """ # noqa E501 |
| 659 | + shape = self._get_operand(shape) |
| 660 | + |
| 661 | + data = { |
| 662 | + "shape": Parts.Part__Fillet.value, |
| 663 | + "name": name if name else self._new_name("Fillet"), |
| 664 | + "parameters": { |
| 665 | + "Base": shape, |
| 666 | + "Edge": edge, |
| 667 | + "Radius": radius, |
| 668 | + "Placement": {"Position": [0, 0, 0], "Axis": [0, 0, 1], "Angle": 0}, |
| 669 | + }, |
| 670 | + } |
| 671 | + self.set_visible(shape, False) |
| 672 | + return self.add_object(OBJECT_FACTORY.create_object(data, self)) |
| 673 | + |
| 674 | + def _get_operand(self, shape: str | int | None, default_idx: int = -1): |
| 675 | + if isinstance(shape, str): |
| 676 | + if shape not in self.objects: |
| 677 | + raise ValueError(f"Unknown object {shape}") |
| 678 | + elif isinstance(shape, int): |
| 679 | + shape = self.objects[shape] |
| 680 | + else: |
| 681 | + shape = self.objects[default_idx] |
| 682 | + |
| 683 | + return shape |
| 684 | + |
| 685 | + def _get_boolean_operands(self, shape1: str | int | None, shape2: str | int | None): |
599 | 686 | if len(self.objects) < 2:
|
600 | 687 | raise ValueError(
|
601 | 688 | "Cannot apply boolean operator if there are less than two objects in the document." # noqa E501
|
602 | 689 | )
|
603 | 690 |
|
604 |
| - if isinstance(shape1, str): |
605 |
| - if shape1 not in objects: |
606 |
| - raise ValueError(f"Unknown object {shape1}") |
607 |
| - elif isinstance(shape1, int): |
608 |
| - shape1 = objects[shape1] |
609 |
| - else: |
610 |
| - shape1 = objects[-2] |
611 |
| - |
612 |
| - if isinstance(shape2, str): |
613 |
| - if shape2 not in objects: |
614 |
| - raise ValueError(f"Unknown object {shape2}") |
615 |
| - elif isinstance(shape2, int): |
616 |
| - shape2 = objects[shape2] |
617 |
| - else: |
618 |
| - shape2 = objects[-1] |
| 691 | + shape1 = self._get_operand(shape1, -2) |
| 692 | + shape2 = self._get_operand(shape2, -1) |
619 | 693 |
|
620 | 694 | return shape1, shape2
|
621 | 695 |
|
@@ -676,6 +750,8 @@ class Config:
|
676 | 750 | IFuse,
|
677 | 751 | ISphere,
|
678 | 752 | ITorus,
|
| 753 | + IFillet, |
| 754 | + IChamfer, |
679 | 755 | ]
|
680 | 756 | metadata: Optional[ShapeMetadata]
|
681 | 757 | _caddoc = Optional[CadDocument]
|
@@ -742,3 +818,5 @@ def create_object(
|
742 | 818 | OBJECT_FACTORY.register_factory(Parts.Part__MultiFuse.value, IFuse)
|
743 | 819 | OBJECT_FACTORY.register_factory(Parts.Part__Sphere.value, ISphere)
|
744 | 820 | OBJECT_FACTORY.register_factory(Parts.Part__Torus.value, ITorus)
|
| 821 | +OBJECT_FACTORY.register_factory(Parts.Part__Chamfer.value, IChamfer) |
| 822 | +OBJECT_FACTORY.register_factory(Parts.Part__Fillet.value, IFillet) |
0 commit comments