Dessia-tech / volmdlr

A python VOLume MoDeLeR computations-oriented with STEP support for import/export
GNU Lesser General Public License v2.1
26 stars 10 forks source link

FEAT : Implement reference_path for primitives #1234

Open GhislainJ opened 8 months ago

GhislainJ commented 8 months ago

There is no implementation

User should be able to store reference_path for some 3D elements (only primitives ?).

As it is also need for plot_data, and thus 2D representation, it would also enable to carry the reference_path to the plot_data method of a volmdlr object.

As part of platform improvements, we want to be able to add interactions between forms and displayed objects as previews. For example, let's say you are, while filling a form, showing a 3D preview of an object. While hovering a 3D part in the display preview, we want to highlight the equivalent part of form input. (n-th line corresponding to the n-th subobject, for ex). Inversely, we also want to be able to look for the corresponding mesh of a form input

I made a first POC of this only for ClosedRoundedLineSegments, and it seems to work fine with a simple implementation :

primitives2d.py

class ClosedRoundedLineSegments2D(RoundedLineSegments2D, wires.Contour2D):
    """
    Defines a polygon with some rounded corners.

    :param points: Points used to draw the wire
    :type points: List of Point2D
    :param radius: Radius used to connect different parts of the wire
    :type radius: {position1(n): float which is the radius linked the n-1 and n+1 points, position2(n+1):...}
    :param reference_path: A path carried from object to subobject in order to reference the path to route object.
    :type reference_path: str with the pattern '#/path/to/.../element'
    """

    def __init__(self, points: List[volmdlr.Point2D], radius: Dict[int, float],
                 adapt_radius: bool = False, reference_path: str = "#", name: str = ''):
        RoundedLineSegments2D.__init__(self, points, radius, adapt_radius=adapt_radius, name='')
        self.closed = True
        wires.Contour2D.__init__(self, primitives=self._primitives(), reference_path=reference_path, name=name)

    def copy(self, deep=True, memo=None):
        """Returns a copy of the object."""
        return self.__class__([point.copy(deep, memo) for point in self.points], self.radius.copy(),
                              self.adapt_radius, reference_path=self.reference_path, name='copy_' + self.name)

wires.py

class Contour2D(ContourMixin, Wire2D):
    """
    A collection of 2D primitives forming a closed wire2D.

    TODO : center_of_mass and second_moment_area should be changed accordingly
    to area considering the triangle drawn by the arcs
    """
    _non_data_hash_attributes = ['_internal_arcs', '_external_arcs',
                                 '_polygon', '_straight_line_contour_polygon',
                                 'primitive_to_index',
                                 'basis_primitives', '_utd_analysis']
    _non_serializable_attributes = ['_internal_arcs', '_external_arcs',
                                    '_polygon',
                                    '_straight_line_contour_polygon',
                                    'primitive_to_index',
                                    'basis_primitives', '_utd_analysis']

    def __init__(self, primitives: List[volmdlr.edges.Edge], reference_path: str = "#",
                 name: str = ''):
        Wire2D.__init__(self, primitives, name)
        self._edge_polygon = None
        self._polygon_100_points = None
        self._area = None
        self.reference_path = reference_path

[...]

    def plot_data(self, edge_style: plot_data.EdgeStyle = None, surface_style: plot_data.SurfaceStyle = None):
        """Plot 2D representation of the contour."""
        plot_data_primitives = [item.plot_data() for item in self.primitives]
        return plot_data.Contour2D(plot_data_primitives=plot_data_primitives,
                                   edge_style=edge_style,
                                   surface_style=surface_style,
                                   reference_path=self.reference_path,
                                   name=self.name)

There probably is more to implement here, about copies, to_dict and stuff. This is just the bare minimum to carry reference_path value to plot_data

Giving the following result. Iinteractions are not yet implement on frontend, this is just to prove that the data can be carried and used on frontend :

image

As the priority is relatively high on this one, I can propose a full implementation