-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D
+// Copyright (C) 2007-2024 CEA, EDF
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+// Author : Anthony Geay (CEA/DEN)
#ifndef __INTERPKERNELGEO2DEDGE_HXX__
#define __INTERPKERNELGEO2DEDGE_HXX__
#include "INTERPKERNELDefines.hxx"
-#include "InterpKernelGeo2DComposedEdge.hxx"
#include "InterpKernelException.hxx"
#include "InterpKernelGeo2DBounds.hxx"
#include "InterpKernelGeo2DNode.hxx"
+#include "MCIdType.hxx"
#include <iostream>
#include <vector>
namespace INTERP_KERNEL
{
typedef enum
- {
- SEG = 1,
- ARC_CIRCLE = 4,
- ARC_PARABOL = 8
- } TypeOfFunction;
+ {
+ SEG = 1,
+ ARC_CIRCLE = 4,
+ ARC_PARABOL = 8
+ } TypeOfFunction;
typedef enum
- {
- CIRCLE = 0 ,
- PARABOL = 1
- } TypeOfMod4QuadEdge;
+ {
+ CIRCLE = 0 ,
+ PARABOL = 1
+ } TypeOfMod4QuadEdge;
typedef enum
- {
- START = 5,
- END = 1,
- INSIDE = 2,
- OUT_BEFORE = 3,
- OUT_AFTER = 4
- } TypeOfLocInEdge; //see Edge::OFFSET_FOR_TYPEOFLOCINEDGE
-
+ {
+ START = 5,
+ END = 1,
+ INSIDE = 2,
+ OUT_BEFORE = 3,
+ OUT_AFTER = 4
+ } TypeOfLocInEdge; //see Edge::OFFSET_FOR_TYPEOFLOCINEDGE
+
typedef enum
- {
- FULL_IN_1 = 1,
- FULL_ON_1 = 4,
- FULL_OUT_1 = 2,
- FULL_UNKNOWN = 3
- } TypeOfEdgeLocInPolygon;
+ {
+ FULL_IN_1 = 1,
+ FULL_ON_1 = 4,
+ FULL_OUT_1 = 2,
+ FULL_UNKNOWN = 3
+ } TypeOfEdgeLocInPolygon;
class INTERPKERNEL_EXPORT MergePoints
{
bool isEnd2(unsigned rk) const;
void clear();
unsigned getNumberOfAssociations() const;
+ void updateMergedNodes(mcIdType e1Start, mcIdType e1End, mcIdType e2Start, mcIdType e2End, std::map<mcIdType,mcIdType>& mergedNodes);
+ private:
+ static void PushInMap(mcIdType key, mcIdType value, std::map<mcIdType,mcIdType>& mergedNodes);
private:
unsigned _ass1Start1 : 1;
unsigned _ass1End1 : 1;
unsigned _ass2End2 : 1;
};
+ class Edge;
+ class ComposedEdge;
/*!
* This class is in charge to store an intersection point as result of \b non oververlapping edge intersection.
* This class manages the cases when intersect element is one of the extrimities of edge1 and/or edge2.
Node *getNodeAndReleaseIt() { Node *tmp=_node; _node=0; return tmp; }
~IntersectElement();
private:
- bool _1S;
- bool _1E;
- bool _2S;
- bool _2E;
+ bool _1S; // true if starting point of edge 1 is located exactly on edge 2 (not nearby)
+ bool _1E; // true if ending point of edge 1 is located exactly on edge 2 (not nearby)
+ bool _2S; // true if starting point of edge 2 is located exactly on edge 1 (not nearby)
+ bool _2E; // true if ending point of edge 2 is located exactly on edge 1 (not nearby)
double _chararct_val_for_e1;
double _chararct_val_for_e2;
Node *_node;
class INTERPKERNEL_EXPORT EdgeIntersector
{
protected:
- //! All non symetric methods are relative to 'e1'.
- EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2) { }
+ //! All non symmetric methods are relative to 'e1'.
+ EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2), _earlyInter(0) { }
public:
- virtual ~EdgeIntersector() { }
+ virtual ~EdgeIntersector() { if(_earlyInter) delete(_earlyInter); }
virtual bool keepOrder() const = 0;
+ virtual bool areColinears() const = 0;
//!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called
virtual bool haveTheySameDirection() const = 0;
//!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called
virtual void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const = 0;
//! When true is returned, newNodes should contains at least 1 element. All merging nodes betw _e1 and _e2 extremities must be done.
- bool intersect(const Bounds *whereToFind, std::vector<Node *>& newNodes, bool& order, MergePoints& commonNode);
+ bool intersect(std::vector<Node *>& newNodes, bool& order, MergePoints& commonNode);
//! Should be called only once per association.
- virtual void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) = 0;
+ virtual void areOverlappedOrOnlyColinears(bool& obviousNoIntersection, bool& areOverlapped) = 0;
//! The size of returned vector is equal to number of potential intersections point. The values are so that their are interpretable by virtual Edge::isIn method.
virtual std::list< IntersectElement > getIntersectionsCharacteristicVal() const = 0;
protected:
void obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const;
+ virtual void identifyEarlyIntersection(bool& , bool&, bool&, bool&);
protected:
const Edge& _e1;
const Edge& _e2;
+ IntersectElement *_earlyInter; // Non null if the intersection can be determined early -> see areOverlappedOrOnlyColinears()
};
class INTERPKERNEL_EXPORT SameTypeEdgeIntersector : public EdgeIntersector
/*!
* Deal with an oriented edge of a polygon.
- * An Edge is definied with a start node a end node and an equation of 1D curve.
+ * An Edge is defined with a start node, an end node and an equation of 1D curve.
* All other attributes are mutable because they don't impact these 3 invariant attributes.
- * To be exact start and end node can change (adress) but their location remain
+ * To be exact start and end nodes can change (address) but their location remain
* the same (at precision).
*/
class INTERPKERNEL_EXPORT Edge
void declareOn() const;
void declareIn() const;
void declareOut() const;
+ void initHitStatus() const { _hit=false; }
+ bool getHitStatus() const { return _hit; }
+ void hitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; applySimilarity(xBary,yBary,dimChar); }
+ void unHitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; unApplySimilarity(xBary,yBary,dimChar); }
+ void hitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) hitMeAlone(xBary,yBary,dimChar); }
+ void unHitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) unHitMeAlone(xBary,yBary,dimChar); }
const Bounds& getBounds() const { return _bounds; }
void fillXfigStreamForLoc(std::ostream& stream) const;
Node *getNode(TypeOfLocInEdge where) const { if(where==START) return _start; else if(where==END) return _end; else return 0; }
static Edge *BuildEdgeFrom(Node *start, Node *end);
template<TypeOfMod4QuadEdge type>
static Edge *BuildEdgeFrom(Node *start, Node *middle, Node *end);
+ static Edge *BuildEdgeFrom3Points(const double *start, const double *middle, const double *end);
virtual void update(Node *m) = 0;
//! returns area between this and axe Ox delimited along Ox by _start and _end.
virtual double getAreaOfZone() const = 0;
virtual double getCurveLength() const = 0;
virtual void getBarycenter(double *bary) const = 0;
virtual void getBarycenterOfZone(double *bary) const = 0;
+ //! return the middle of two points
+ virtual void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const = 0;
+ //! return the middle of two points respecting the orientation defined by this (relevant for arc of circle). By default same as getMiddleOfPoints()
+ virtual void getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const;
//! Retrieves a point that is owning to this, well placed for IN/OUT detection of this. Typically midlle of this is returned.
virtual Node *buildRepresentantOfMySelf() const = 0;
//! Given a magnitude specified by sub-type returns if in or not. See getCharactValue method.
static void Interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2,
std::map<int, std::map<int,double> >& result);
virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0;
+ void dumpToCout(const std::map<INTERP_KERNEL::Node *,int>& mapp, int index) const;
bool isEqual(const Edge& other) const;
public:
- void sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const std::map<INTERP_KERNEL::Node *, int>& mapp1, const std::map<INTERP_KERNEL::Node *, int>& mapp2, std::vector<int>& edgesThis);
- virtual void fillGlobalInfoAbs(bool direction, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY,
- std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const = 0;
- virtual void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY,
- std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const = 0;
+ bool sortSubNodesAbs(const double *coo, std::vector<mcIdType>& subNodes);
+ void sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const std::map<INTERP_KERNEL::Node *, mcIdType>& mapp1, const std::map<INTERP_KERNEL::Node *, mcIdType>& mapp2, std::vector<mcIdType>& edgesThis);
virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0;
+ void fillGlobalInfoAbs(bool direction, const std::map<INTERP_KERNEL::Node *,mcIdType>& mapThis, const std::map<INTERP_KERNEL::Node *,mcIdType>& mapOther, mcIdType offset1, mcIdType offset2, double fact, double baryX, double baryY,
+ std::vector<mcIdType>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,mcIdType> mapAddCoo) const;
+ void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,mcIdType>& mapThis, const std::map<INTERP_KERNEL::Node *,mcIdType>& mapOther, mcIdType offset1, mcIdType offset2, double fact, double baryX, double baryY,
+ short skipStartOrEnd,
+ std::vector<mcIdType>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,mcIdType>& mapAddCoo) const;
+
protected:
Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { }
virtual ~Edge();
static int CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2);
- static bool Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
+ static bool Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode,
ComposedEdge& outValForF1, ComposedEdge& outValForF2);
//! The code 'code' is built by method combineCodes
static bool SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code,
ComposedEdge& outVal1, ComposedEdge& outVal2);
protected:
+ mutable bool _hit;
mutable unsigned char _cnt;
mutable TypeOfEdgeLocInPolygon _loc;
Bounds _bounds;