Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
DLR-AMR
GitHub Repository: DLR-AMR/t8code
Path: blob/main/src/t8_cad/t8_cad.hxx
914 views
/*
  This file is part of t8code.
  t8code is a C library to manage a collection (a forest) of multiple
  connected adaptive space-trees of general element classes in parallel.

  Copyright (C) 2025 the developers

  t8code is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  t8code is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with t8code; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/** \file t8_cad.hxx
 * This file implements the t8_cad class. It manages OpenCASCADE shapes and implements
 * helper functions for working with the shapes.
 */

#ifndef T8_CAD_HXX
#define T8_CAD_HXX

#include <gp_Pnt.hxx>
#include <TopExp.hxx>
#include <Geom_Surface.hxx>
#include <Geom_Curve.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <optional>
#include <span>

/**
 * This class manages OpenCASCADE shapes and implements helper functions for working with the shapes.
*/
struct t8_cad
{
 public:
  /**
    * Constructor of the cad shape.
    * The shape is initialized based on a .brep file with the given prefix.
    * The internal structure extracts and stores geometric information such as
    * vertices, edges, and faces from this file. The number and type of vertices
    * should match the tree type (quad/hex/tri), and the cad data must be valid.
    * This constructor is intended for general use, including file-based mesh creation.
    *
    * \param [in] fileprefix  Prefix of a .brep file from which to extract cad geometry.
    */
  t8_cad (std::string fileprefix);

  /**
    * Constructor of the cad shape.
    * The shape is initialized directly from an existing TopoDS_Shape.
    * This constructor is especially useful for use in scripts, testing,
    * or integration with mesh generators that already provide geometry in memory.
    * It avoids file I/O and allows full control over the CAD input.
    *
    * \param [in] cad_shape  cad shape geometry object.
    */
  t8_cad (const TopoDS_Shape cad_shape);

  /**
   * Constructor of the cad shape for testing purposes. Sets an invalid cad_shape.
   */
  t8_cad ();

  /** Check if a cad_curve is a line.
   * \param [in] curve_index      The index of the cad_curve.
   * \return                      1 if curve is a line, 0 if curve is not a line.
   */
  int
  t8_geom_is_line (const int curve_index) const;

  /** Check if a cad_surface is a plane.
   * \param [in] surface_index      The index of the cad_surface.
   * \return                        1 if surface is a plane linear, 0 if surface is not a plane.
   */
  int
  t8_geom_is_plane (const int surface_index) const;

  /** Get a cad vertex from the cad_shape.
   * \param [in] index      The index of the vertex in the cad_shape.
   * \return                The cad vertex.
   */
  const TopoDS_Vertex
  t8_geom_get_cad_vertex (const int index) const;

  /** Get a cad edge from the cad_shape.
   * \param [in] index      The index of the edge in the cad_shape.
   * \return                The cad edge.
   */
  const TopoDS_Edge
  t8_geom_get_cad_edge (const int index) const;

  /** Get a cad face from the cad_shape.
   * \param [in] index      The index of the face in the cad_shape.
   * \return                The cad face.
   */
  const TopoDS_Face
  t8_geom_get_cad_face (const int index) const;

  /** Get a cad point from the cad_shape.
   * \param [in] index      The index of the point in the cad_shape.
   * \return                The cad point.
   */
  const gp_Pnt
  t8_geom_get_cad_point (const int index) const;

  /** Get a cad curve from the cad_shape.
   * \param [in] index      The index of the curve in the cad_shape.
   * \return                The cad curve.
   */
  const Handle_Geom_Curve
  t8_geom_get_cad_curve (const int index) const;

  /** Get a cad surface from the cad_shape.
   * \param [in] index      The index of the surface in the cad_shape.
   * \return                The cad surface.
   */
  const Handle_Geom_Surface
  t8_geom_get_cad_surface (const int index) const;

  /** Get the cad_shape_vertex2edge_map.
   * \return                The cad_shape_vertex_map.
   */
  const TopTools_IndexedMapOfShape
  t8_geom_get_cad_shape_vertex_map () const;

  /** Get the cad_shape_edge2face_map.
   * \return                The cad_shape_edge_map.
   */
  const TopTools_IndexedMapOfShape
  t8_geom_get_cad_shape_edge_map () const;

  /** Get the cad_shape_face_map.
   * \return                The cad_shape_face_map.
   */
  const TopTools_IndexedMapOfShape
  t8_geom_get_cad_shape_face_map () const;

  /** Check if two cad points share a common cad edge.
   * \param [in]  vertex1_index  The index of the first cad point.
   * \param [in]  vertex2_index  The index of the second cad point.
   * \return                    Index of the shared edge. 0 if there is no shared edge.
   */
  int
  t8_geom_get_common_edge_of_vertices (const int vertex1_index, const int vertex2_index) const;

  /** Check if two cad edges share a common cad face.
   * \param [in]  edge1_index    The index of the first cad edge.
   * \param [in]  edge2_index    The index of the second cad edge.
   * \return                    Index of the shared face. 0 if there is no shared face.
   */
  int
  t8_geom_get_common_face_of_edges (const int edge1_index, const int edge2_index) const;

  /** Check if a cad vertex and cad edge share a common face.
   * \param [in]  vertex_index   The index of the cad vertex.
   * \param [in]  edge_index     The index of the cad edge.
   * \return                     Index of the shared face. 0 if there is no shared face.
   */
  int
  t8_geom_get_common_face_of_vertex_and_edge (const int vertex_index, const int edge_index) const;

  /** Check if two cad vertices share a common cad face.
   * \param [in]  vertex1_index The index of the first cad edge.
   * \param [in]  vertex2_index The index of the second cad edge.
   * \return                    Index of the shared face. 0 if there is no shared face.
   */
  int
  t8_geom_get_common_face_of_vertices (const int vertex1_index, const int vertex2_index) const;

  /** Check if a cad vertex lies on an cad edge.
   * \param [in]  vertex_index   The index of the cad vertex.
   * \param [in]  edge_index     The index of the cad edge.
   * \return                    1 if vertex lies on edge, otherwise 0.
   */
  int
  t8_geom_is_vertex_on_edge (const int vertex_index, const int edge_index) const;

  /** Check if a cad vertex lies on an cad edge.
   * \param [in]  edge_index     The index of the cad vertex.
   * \param [in]  face_index     The index of the cad edge.
   * \return                    1 if vertex lies on edge, otherwise 0.
   */
  int
  t8_geom_is_edge_on_face (const int edge_index, const int face_index) const;

  /** Check if a cad vertex lies on an cad face.
   * \param [in]  vertex_index   The index of the cad vertex.
   * \param [in]  face_index     The index of the cad face.
   * \return                    1 if vertex lies on face, otherwise 0.
   */
  int
  t8_geom_is_vertex_on_face (const int vertex_index, const int face_index) const;

  /** Returns true if \a vertex_index is on a seam of \a edge_index.
   * A seam is a vertex which connects a curve to itself.
   *
   * \param [in] vertex_index   The index of the cad vertex.
   * \param [in] edge_index     The index of the cad edge.
   * \return true if the vertex is a seam. false otherwise.
   */
  bool
  t8_geom_vertex_is_seam (const int vertex_index, const int edge_index) const;

  /** Returns true if \a vertex_index is on a seam of \a face_index.
   * A seam is an edge which connects a surface to itself.
   *
   * \param [in] vertex_index   The index of the cad vertex.
   * \param [in] face_index     The index of the cad face.
   * \return true if the edge is a seam. false otherwise.
   */
  bool
  t8_geom_vertex_is_on_seam_edge (const int vertex_index, const int face_index) const;

  /** Returns true if \a edge_index is a seam of \a face_index.
   * A seam is an edge which connects a surface to itself.
   *
   * \param [in] edge_index   The index of the cad edge.
   * \param [in] face_index   The index of the cad face.
   * \return true if the edge is a seam. false otherwise.
   */
  bool
  t8_geom_edge_is_seam (const int edge_index, const int face_index) const;

  /** Retrieves the parameter of an cad vertex on an cad edge.
   * The vertex has to lie on the edge.
   * \warning If the edge is closed in any direction and the vertex is the closing bound,
   * it is random which side of the closed edge the parameter is from. The parameter
   * is correct, but for curved elements it has to be checked if the parameter has to be
   * converted onto the other bound.
   * \param [in]  vertex_index            The index of the cad vertex.
   * \param [in]  edge_index              The index of the cad edge.
   * \param [out] edge_param              The parameter of the vertex on the edge.
   * \param [in]  reference_edge_param    Reference parameters on the edge.
   */
  void
  t8_geom_get_parameter_of_vertex_on_edge (const int vertex_index, const int edge_index, double *edge_param,
                                           std::optional<double> reference_edge_param = std::nullopt) const;

  /** Retrieves the parameters of an cad vertex on a cad face.
   * The vertex has to lie on the face.
   * If the vertex is in a seam, the vertex closer to the \a reference_face_params is chosen.
   * \warning If the face is closed in any direction and the vertex is on the seam and no reference
   * parameters are provided it is random which side of the closed face the parameters are from.
   * The parameters are correct, but for curved elements it has to be checked if the parameters have to be
   * converted onto the other bound.
   * \param [in]  vertex_index              The index of the cad vertex.
   * \param [in]  face_index                The index of the cad face.
   * \param [out] face_params               The parameters of the vertex on the face.
   * \param [in]  reference_face_params     Reference parameters on the surface.
   */
  void
  t8_geom_get_parameters_of_vertex_on_face (const int vertex_index, const int face_index, double face_params[2],
                                            std::optional<std::span<const double, 2>> reference_face_params
                                            = std::nullopt) const;

  /** Converts the parameters of a cad edge to the corresponding parameters on a cad face.
   * The edge has to lie on the face.
   * If the edge is a seam, the edge closer to the \a reference_face_params is chosen.
   * \warning If the face is closed in any direction and the edge is the seam and no reference
   * parameters are provided it is random which side of the closed face the parameters are from.
   * The parameters are correct, but for curved elements it has to be checked if the parameters have to be
   * converted onto the other side of the seam.
   * \param [in]  edge_index                The index of the cad edge, which parameters should be converted to face parameters.
   * \param [in]  face_index                The index of the cad face, on to which the edge parameters should be converted.
   * \param [in]  edge_param                The parameter on the edge.
   * \param [out] face_params_out           The corresponding parameters on the face.
   * \param [in]  reference_face_params     Reference parameters on the surface.
   */
  void
  t8_geom_edge_parameter_to_face_parameters (const int edge_index, const int face_index, const double edge_param,
                                             double face_params_out[2],
                                             std::optional<std::span<const double, 2>> reference_face_params
                                             = std::nullopt) const;

  /** Finds the parametric bounds of an cad face.
   * \param [in]  surface_index   The index of the cad face.
   * \param [out] bounds          The parametric bounds of the cad face.
   */
  void
  t8_geom_get_face_parametric_bounds (const int surface_index, double *bounds) const;

  /** Finds the parametric bounds of an cad edge.
   * \param [in]  edge_index   The index of the cad edge.
   * \param [out] bounds       The parametric bounds of the cad edge.
   */
  void
  t8_geom_get_edge_parametric_bounds (const int edge_index, double *bounds) const;

  /** Checks if an edge is closed.
   * \param [in]  edge_index   The index of the closed edge.
   * \return                   true if edge is closed
   */
  bool
  t8_geom_edge_is_closed (int edge_index) const;

  /** Checks if a surface is closed in any direction.
   * \param [in]  geometry_index   The index of the closed geometry.
   * \return                       true if geometry is closed in any direction.
   */
  bool
  t8_geom_surface_is_closed (int geometry_index) const;

  /** Checks if a surface is closed in its U direction or V direction.
   * \param [in]  geometry_index   The index of the closed geometry.
   * \param [in]  direction        The direction, which should be check for closeness.
   *                               0 stands for the U direction and 1 for the V direction.
   * \return                       true if geometry is closed in the given direction.
   */
  bool
  t8_geom_surface_is_closed (int geometry_index, int direction) const;

 private:
  TopoDS_Shape cad_shape;                          /**< cad geometry */
  TopTools_IndexedMapOfShape cad_shape_vertex_map; /**< Map of all TopoDS_Vertex. */
  TopTools_IndexedMapOfShape cad_shape_edge_map;   /**< Map of all TopoDS_Edge. */
  TopTools_IndexedMapOfShape cad_shape_face_map;   /**< Map of all TopoDS_Face. */
  TopTools_IndexedDataMapOfShapeListOfShape
    cad_shape_vertex2edge_map; /**< Maps all TopoDS_Vertex to all its connected TopoDS_Edge */
  TopTools_IndexedDataMapOfShapeListOfShape
    cad_shape_edge2face_map; /**< Maps all TopoDS_Edge to all its connected TopoDS_Face */
  TopTools_IndexedDataMapOfShapeListOfShape
    cad_shape_vertex2face_map; /**< Maps all TopoDS_Vertex to all its connected TopoDS_Face */
};

#endif /* !T8_CAD_HXX */