////////////////////////////////////////////////////////////////////////////////
/** 
  \file
  \brief \ru Инструмент для итерационного построения видов многосегментного сечения.
         \en The tool for the iterative construction of multi-segment section. \~

*/
////////////////////////////////////////////////////////////////////////////////

#ifndef __MAP_SECTION_COMPLEX_H
#define __MAP_SECTION_COMPLEX_H


#include <templ_ss_array.h>
#include <mb_placement3d.h>
#include <mb_axis3d.h>
#include <mb_operation_result.h>
#include <map_lump.h>


class  MATH_CLASS  MbContour;
class  MATH_CLASS  MbPlacement3D;
class  MATH_CLASS  MbSolid;
class  MATH_CLASS  MbSectionMap;


//------------------------------------------------------------------------------
/** \brief \ru Интерфейс итератора видов сечений.
           \en The interface of iterator of section views. \~
  \details \ru Интерфейс итератора видов сечений.\n
           \en The interface of iterator of section views.\n \~
  \ingroup Mapping
*/ 
// ---
struct MATH_CLASS MbSectionMapIteratorAbs {

  /// \ru Удалить. \en Remove. 
  virtual void            Release() = 0;
  /// \ru Сбросить итератор в начало. \en Set the iterator to the begining. 
  virtual void            Reset() = 0;
  /// \ru Есть ли еще итерации. \en Whether there are any iteration.     
  virtual bool            More() const = 0;
  
  /** \brief \ru Следующее сечение.
             \en The next section. \~
    \details \ru Следующее сечение.\n
             \en The next section.\n \~
    \return \ru Всегда не нулевой указатель.
            \en Always non-null pointer. \~
  */
  virtual MbSectionMap *  Next() = 0;

  /// \ru Результат последнего действия (итерации). \en The last iteration result. 
  virtual MbResultType    GetLastResult() const = 0;  

  /// \ru Установить интерфейс хранилища аннатационных объектов. \en Set the interface of the annotation objects storage. 
  virtual void            SetAnnObjectStore   ( ItAnnObjectStore * ) = 0;
  /// \ru Установить условные обозначения. \en Set conventional notations. 
  virtual void            SetSymbolObjects    ( RPArray<MbSymbol> & ) = 0;
  /// \ru Установить интерфейс хранилища условных обозначений. \en Set the interface of the conventional notations storage. 
  virtual void            SetSymbolObjectStore( ItSymbolObjectStore * ) = 0;

  /// \ru Установить пространственные точки. \en Set spatial points. 
  virtual void            SetSpacePoints( RPArray<MbSpacePoints> & ) = 0;
  /// \ru Установить пространственные кривые. \en Set spatial curves. 
  virtual void            SetSpaceCurves( RPArray<MbSpaceCurves> & ) = 0;

}; // MbSectionMapIteratorAbs


//------------------------------------------------------------------------------
/** \brief \ru Итератор видов сечений тела.
           \en The iterator of section views of solid. \~
  \details \ru Итератор видов сечений тела. Реализационный. \n
    Замечания по итератору:\n
    - контур разреза\сечения не должен быть самопересекающимся;\n
    - контур разреза\сечения состоит только из отрезков;\n
    - виды, сечений, порождаемых итератором видов не зависят друг от друга,\n
      но влияют на построение линий разрыва между соседними видами.
           \en The iterator of section views of solid. Implementational. \n
    Remarks on iterator:\n
    - a contour of cutaway\section must not be self-intersecting;\n
    - a contour of cutaway\section consists only of segments;\n
    - section views generated by iterator of views don't depend on each other\n
      but affect on the construction of discontinuity lines between neighboring views. \~   
  \ingroup Mapping
*/ 
// ---
class MATH_CLASS MbSectionMapIterator {

public:
  
  /** \brief \ru Итератор по множеству моделей тел.
             \en The iterator by a set of solids models. \~
    \details \ru Итератор по множеству моделей тел.\n
             \en The iterator by a set of solids models.\n \~
    \param[in] lumps          - \ru Набор тел с матрицами и признаками рассечения.
                                \en A set of solids with matrices and dissections attributes. \~
    \param[in] place          - \ru Плоскость секущего вида.
                                \en A plane of secant view. \~
    \param[in] isViewCut      - \ru Признак вида-разреза (а не сечения).
                                \en An attribute of a cutaway-view (not section). \~
    \param[in] isDismantel    - \ru Разнесенный вид сборки.
                                \en Dismantled view of the assembly. \~
    \param[in] ncontour       - \ru Контур разреза\сечения.
                                \en A cutaway\section contour. \~
    \param[in] ncontourNames  - \ru Именователь контура.
                                \en A name-maker of contour. \~
    \param[in] part           - \ru Сторона отсечения. Имеет значение знак числа.
                                \en A cut-off side. It have a value of the number sign. \~
    \param[in] visMode        - \ru Настройки видимости следов проецируемых объектов.
                                \en Visibility mode of mapping. \~
    \param[in] doCommonNaming - \ru Именовать все промежуточные тела вместе.
                                \en Do common naming of all intermediate bodies. \~
    \param[in] obj_version    - \ru Математическая версия.
                                \en Mathematical version. \~
    \return \ru Итератор видов сечений.
            \en The iterator of section views. \~
  */
  static  MbSectionMapIteratorAbs & Create (       RPArray<MbMappingLumps> & lumps,
                                             const MbPlacement3D           & place,
                                                   bool                      isViewCut,
                                                   bool                      isDismantel,
                                             const MbContour               & ncontour,
                                             const MbSNameMaker            & ncontourNames,
                                                   ptrdiff_t                 part,
                                             const MbMapVisibilityMode     & visMode,
                                                   bool                      doCommonNaming,
                                                   VERSION                   obj_version );  // _BUG_18777_DEF_
  
  /** \brief \ru Валидность контура.
             \en The validity of the contour. \~
    \details \ru Валидность контура для построения сечений.\n
      Контур валидный, если он:\n
      - не имеет самопересечений,\n
      - состоит из отрезков,\n
      - если каждый отрезок имеет габарит с длиной и шириной, превышающими погрешность.
             \en The validity of the contour for the construction of sections.\n
      The contour is valid if it:\n
      - has no self-intersections,\n
      - consists of segments,\n
      - if an each segment has a bounding box with the length and width which are greater than the tolerance. \~
    \return \ru Код разельтата.
            \en A result code. \~
  */
  static  MbResultType    ContourValidityCheck( const MbContour & contour );

  /** \brief \ru Распознать ортоперпендекулярное сечение.
             \en Recognize an ortho-perpendicular section. \~
    \details \ru Распознать ортоперпендекулярное сечение.\n 
      При этом контур должен удовлетворять условиям:\n
      - быть валидным для построения сечения,\n
      - состоять более чем из двух сегментов,\n
      - первый и последний сегменты должны быть параллельны и сонаправлены,\n
      - каждый сегмент контура должен быть или перпендикулярен предыдущему сегменту, 
        или параллелен и сонаправлен с предыдущим сегментом,\n
      - должна присутствовать хотя бы одна пара взаимноперпендикулярных соседних сегментов.
             \en Recognize an ortho-perpendicular section.\n 
      The contour must satisfy conditions:\n
      - to be valid for the section construction,\n
      - to consist of more than two segments,\n
      - the first and the second segments must be parallel and co-directed,\n
      - an each contour segment must be perpendicular to the previous segment, 
        or parallel and co-directed to the previous segment,\n
      - must have at least one pair of mutually perpendicular adjacent segments. \~
    \return \ru Признак ортоперпендикулярного сечения.
            \en An attribute of ortho-perpendicular section. \~
  */
  static  bool            IsOrthonormalSectionContour( const MbContour & contour );
}; // MbSectionMapIterator

  
//------------------------------------------------------------------------------
/** \brief \ru Итератор местных видов сечений тела.
           \en The iterator of local views of sections of solid. \~
  \details \ru Итератор местных видов сечений тела.\n
           \en The iterator of local views of sections of solid.\n \~
  \ingroup Mapping
  */ 
// ---
class MATH_CLASS MbLocalSectionMapIterator {

public:
  /** \brief \ru Итератор по множеству моделей тел.
             \en The iterator by a set of solids models. \~
    \details \ru Итератор по множеству моделей тел.\n
             \en The iterator by a set of solids models.\n \~
    \param[in] lumps          - \ru Набор тел с матрицами и признаками рассечения.
                                \en A set of solids with matrices and dissections attributes. \~
    \param[in] place          - \ru Плоскость секущего вида.
                                \en A plane of secant view. \~
    \param[in] isViewCut      - \ru Признак вида-разреза (а не сечения).
                                \en An attribute of a cutaway-view (not section). \~
    \param[in] isDismantel    - \ru Разнесенный вид сборки.
                                \en Dismantled view of the assembly. \~
    \param[in] contour        - \ru Контур разреза\сечения.
                                \en A cutaway\section contour. \~
    \param[in] contourNames   - \ru Именователь контура.
                                \en A name-maker of contour. \~
    \param[in] visMode        - \ru Настройки видимости следов проецируемых объектов.
                                \en Visibility mode of mapping. \~
    \param[in] doCommonNaming - \ru Именовать все промежуточные тела вместе.
                                \en Do common naming of all intermediate bodies. \~
    \return \ru Итератор местных видов сечений.
            \en The iterator of local views of sections. \~
  */
  static  MbSectionMapIteratorAbs & Create (       RPArray<MbMappingLumps> & lumps,
                                             const MbPlacement3D           & place,
                                                   bool                      isViewCut,
                                                   bool                      isDismantel,
                                             const MbContour               & contour,
                                             const MbSNameMaker            & contourNames,
                                             const MbMapVisibilityMode     & visMode,
                                                   bool                      doCommonNaming );
}; // MbLocalSectionMapIterator


//------------------------------------------------------------------------------
/** \brief \ru Построение плоскости простого сечения/разреза.
           \en Construction of a plane of simple section/cutaway. \~
  \details \ru Построение плоскости сечения/разреза, если линия разреза состоит из одного сегмента.
           \en Construction of a plane of section/cutaway if a cutaway line consists of one segment. \~
  \param[in]  m_place   - \ru Плоскость линии разреза.
                          \en A plane of cutaway line. \~
  \param[in]  m_segment - \ru Сегмент линии разреза.
                          \en A segment of a cutaway line. \~
  \param[in]  m_left    - \ru Направление взгляда.
                          \en Direction of view.\~
  \param[out] secPlace  - \ru Плоскость сечения.
                          \en A plane of a section. \~
*/
//---
MATH_FUNC(bool) FormFirstSectionPlane( const MbPlacement3D & m_place, const MbCurve & m_segment, bool m_left,
                                       MbPlacement3D & secPlace );

 
//------------------------------------------------------------------------------
/** \brief \ru Преобразование плоскости вида к плоскости отображения проекции.
           \en The view plane convert to the plane of the projection. \~
  \details \ru Преобразование плоскости вида к плоскости отображения проекции.
               Нормаль плоскости вида направлена против вектора взгляда.
           \en The view plane convert to the plane of the projection. 
               Normal to the view plane is directed against the view vector. \~
  \param[in,out] place  - \ru Плоскость вида (отображения проекции).
                          \en A view plane (A plane of the projection). \~
  \param[in]  viewDir - \ru Вектор взгляда.
                        \en A view vector. \~
*/
// ---
inline
void MappingVPtoMP( MbPlacement3D & place, const MbVector & viewDir )
{
  if ( ::fabs(viewDir.x) > Math::lengthEpsilon || ::fabs(viewDir.y) > Math::lengthEpsilon ) {
    MbVector vDir( viewDir );
    vDir.Normalize();
    vDir.Perpendicular();
    MbVector3D rotateV;
    place.VectorOn( vDir, rotateV );
    MbAxis3D rotateAxis ( place.GetOrigin(), rotateV );
    place.Rotate( rotateAxis, -M_PI_2 );
  }
}


#endif // __MAP_SECTION_COMPLEX_H
