gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
filterElements.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <algorithm>
7 #include <vector>
8 #include <set>
9 #include "GmshDefines.h"
10 #include "filterElements.h"
11 #include "MElement.h"
12 #include "MTriangle.h"
13 #include "MQuadrangle.h"
14 #include "MLine.h"
15 #include "rtree.h"
16 #include "robustPredicates.h"
17 
18 void MElementBB(void *a, double *min, double *max);
19 int MElementInEle(void *a, double *x);
20 
22  bool _overlap;
24  std::vector<MElement *> _notOverlap;
25  MElement_Wrapper(MElement *e, const std::vector<MElement *> &notOverlap)
26  : _overlap(false), _e(e), _notOverlap(notOverlap)
27  {
28  std::sort(_notOverlap.begin(), _notOverlap.end());
29  }
30 };
31 
51 inline double orientationTest(double a[2], double b[2], double c[2])
52 {
53  double s = -robustPredicates::orient2d(a, b, c);
54  return s >= 0 ? 1.0 : s <= 0 ? -1.0 : 0.0;
55 }
56 
57 inline double orientationTest(MVertex *va, MVertex *vb, MVertex *vc)
58 {
59  double a[2] = {va->x(), va->y()};
60  double b[2] = {vb->x(), vb->y()};
61  double c[2] = {vc->x(), vc->y()};
62  return orientationTest(a, b, c);
63 }
64 
65 inline double orientationTest(SVector3 &va, SVector3 &vb, SVector3 &vc)
66 {
67  double a[2] = {va.x(), va.y()};
68  double b[2] = {vb.x(), vb.y()};
69  double c[2] = {vc.x(), vc.y()};
70  return orientationTest(a, b, c);
71 }
72 
73 bool intersectEdge2d(const MEdge &ed1, const MEdge &ed2)
74 {
75  double xmax1 = std::max(ed1.getVertex(0)->x(), ed1.getVertex(1)->x());
76  double xmax2 = std::max(ed2.getVertex(0)->x(), ed2.getVertex(1)->x());
77  double ymax1 = std::max(ed1.getVertex(0)->y(), ed1.getVertex(1)->y());
78  double ymax2 = std::max(ed2.getVertex(0)->y(), ed2.getVertex(1)->y());
79  double xmin1 = std::min(ed1.getVertex(0)->x(), ed1.getVertex(1)->x());
80  double xmin2 = std::min(ed2.getVertex(0)->x(), ed2.getVertex(1)->x());
81  double ymin1 = std::min(ed1.getVertex(0)->y(), ed1.getVertex(1)->y());
82  double ymin2 = std::min(ed2.getVertex(0)->y(), ed2.getVertex(1)->y());
83 
84  if(xmax1 < xmin2) return false;
85  if(xmax2 < xmin1) return false;
86  if(ymax1 < ymin2) return false;
87  if(ymax2 < ymin1) return false;
88 
89  if(xmin1 > xmax2) return false;
90  if(xmin2 > xmax1) return false;
91  if(ymin1 > ymax2) return false;
92  if(ymin2 > ymax1) return false;
93 
94  // ed2.getVertex(0)->x(),ed2.getVertex(0)->y(),ed2.getVertex(1)->x(),ed2.getVertex(1)->y()
95 
96  /* SVector3 a1(ed1.getVertex(0)->x(), ed1.getVertex(0)->y(), 0);
97  SVector3 a2(ed1.getVertex(1)->x(), ed1.getVertex(1)->y(), 0);
98 
99  SVector3 b1(ed2.getVertex(0)->x(), ed2.getVertex(0)->y(), 0);
100  SVector3 b2(ed2.getVertex(1)->x(), ed2.getVertex(1)->y(), 0);
101 
102  SVector3 a = (a1+a2)*0.5;
103  SVector3 b = (b1+b2)*0.5;
104 
105  SVector3 a1l = a + (a2-a1)*0.55;
106  SVector3 a2l = a - (a2-a1)*0.55;
107 
108  SVector3 b1l = b + (b2-b1)*0.55;
109  SVector3 b2l = b - (b2-b1)*0.55;
110 
111  if (orientationTest (a1l, a2l, b1l) * orientationTest (a1l, a2l, b2l) <= 0 &&
112  orientationTest (b1l, b2l, a1l) * orientationTest (b1l, b2l, a2l) <= 0 )
113  return true;
114  */
115  if(ed1.getVertex(0) == ed2.getVertex(0) ||
116  ed1.getVertex(0) == ed2.getVertex(1) ||
117  ed1.getVertex(1) == ed2.getVertex(0) ||
118  ed1.getVertex(1) == ed2.getVertex(1))
119  return false;
120 
121  if((orientationTest(ed1.getVertex(0), ed1.getVertex(1), ed2.getVertex(0)) *
122  orientationTest(ed1.getVertex(0), ed1.getVertex(1), ed2.getVertex(1)) <=
123  0) &&
124  (orientationTest(ed2.getVertex(0), ed2.getVertex(1), ed1.getVertex(0)) *
125  orientationTest(ed2.getVertex(0), ed2.getVertex(1), ed1.getVertex(1)) <=
126  0))
127  return true;
128  return false;
129 }
130 
132 {
133  for(int i = 0; i < e1->getNumEdges(); i++) {
134  MEdge ed1 = e1->getEdge(i);
135  for(int j = 0; j < e2->getNumEdges(); j++) {
136  MEdge ed2 = e2->getEdge(j);
137  if(intersectEdge2d(ed1, ed2)) {
138  // printf("apero time nnodes %d %d partitions %d %d : %g %g -- %g %g
139  // vs %g %g -- %g %g\n",
140  // e1->getNumVertices(),e2->getNumVertices(),
141  // e1->getPartition(),e2->getPartition(),
142  // ed1.getVertex(0)->x(),ed1.getVertex(0)->y(),ed1.getVertex(1)->x(),ed1.getVertex(1)->y(),
143  // ed2.getVertex(0)->x(),ed2.getVertex(0)->y(),ed2.getVertex(1)->x(),ed2.getVertex(1)->y()
144  // );
145  return true;
146  }
147  }
148  }
149  return false;
150 }
151 
152 bool rtree_callback(MElement *e1, void *pe2)
153 {
154  MElement_Wrapper *wrapper = static_cast<MElement_Wrapper *>(pe2);
155  MElement *e2 = wrapper->_e;
156 
157  if(std::binary_search(wrapper->_notOverlap.begin(),
158  wrapper->_notOverlap.end(), e1))
159  return true;
160 
161  // for (int i=0;i<e1->getNumVertices();i++){
162  // for (int j=0;j<e2->getNumVertices();j++){
163  // if(e1->getVertex(i) == e2->getVertex(j))return true;
164  // }
165  // }
166 
167  if(e1->getDim() <= 2 && e2->getDim() <= 2) {
168  wrapper->_overlap = overlap2D(e1, e2);
169  return !wrapper->_overlap;
170  }
171  Msg::Error("overlapping of elements in 3D not done yet");
172  return true;
173 }
174 
176  : public std::binary_function<MElement *, MElement *, bool> {
177  bool operator()(const MElement *f1, const MElement *f2) const
178  {
179  return f1->getPartition() < f2->getPartition();
180  }
181 };
182 
183 void filterColumns(std::vector<MElement *> &elem,
184  std::map<MElement *, std::vector<MElement *> > &_elemColumns)
185 {
186  std::sort(elem.begin(), elem.end());
187  std::vector<MElement *> toKeep;
188  for(auto it = _elemColumns.begin(); it != _elemColumns.end(); ++it) {
189  const std::vector<MElement *> &c = it->second;
190  std::size_t MAX = c.size();
191  // printf("size of column %d\n",c.size());
192  for(std::size_t i = 0; i < c.size(); i++) {
193  if(!std::binary_search(elem.begin(), elem.end(), c[i])) {
194  MAX = i;
195  break;
196  }
197  }
198  if(!MAX) MAX = 1;
199  // if (MAX != c.size()) printf("MAX = %d c = %d\n",MAX,c.size());
200  for(std::size_t i = 0; i < MAX; i++) {
201  if(orientationTest(c[i]->getVertex(0), c[i]->getVertex(1),
202  c[i]->getVertex(2)) < 0)
203  c[i]->reverse();
204  toKeep.push_back(c[i]);
205  }
206  // for (std::size_t i=MAX;i<c.size();i++){
207  // FIXME !!!
208  // delete c[i];
209  // }
210  }
211  // printf("%d --> %d\n", (int)elem.size(), (int)toKeep.size());
212  elem = toKeep;
213 }
214 
216  std::vector<MLine *> &lines, std::vector<MElement *> &els,
217  std::map<MElement *, std::vector<MElement *> > &_elemColumns,
218  std::map<MElement *, MElement *> &_toFirst)
219 {
220  std::vector<MElement *> newEls;
222 
223  for(std::size_t i = 0; i < lines.size(); i++) {
224  MElement *e = lines[i];
225  double _min[3], _max[3];
226  MElementBB(e, _min, _max);
227  rtree.Insert(_min, _max, e);
228  }
229 
230  for(std::size_t i = 0; i < els.size(); i++) {
231  MElement *e = els[i];
232  double _min[3], _max[3];
233  MElementBB(e, _min, _max);
234  MElement *first = _toFirst[e];
235  MElement_Wrapper w(e, _elemColumns[first]);
236  rtree.Search(_min, _max, rtree_callback, &w);
237  if(w._overlap) {
238  // delete e;
239  }
240  else {
241  rtree.Insert(_min, _max, e);
242  newEls.push_back(e);
243  }
244  }
245  els = newEls;
246 }
247 
248 // WE SHOULD ADD THE BOUNDARY OF THE DOMAIN IN ORDER TO AVOID
249 // ELEMENTS THAT ARE OUTSIDE THE DOMAIN --> FIXME
250 
252  std::vector<MLine *> &bdry, std::vector<MTriangle *> &blTris,
253  std::vector<MQuadrangle *> &blQuads,
254  std::map<MElement *, std::vector<MElement *> > &_elemColumns,
255  std::map<MElement *, MElement *> &_toFirst)
256 {
257  std::vector<MElement *> vvv;
258  vvv.insert(vvv.begin(), blTris.begin(), blTris.end());
259  vvv.insert(vvv.begin(), blQuads.begin(), blQuads.end());
260  Less_Partition lp;
261  std::sort(vvv.begin(), vvv.end(), lp);
262  filterOverlappingElements(bdry, vvv, _elemColumns, _toFirst);
263  filterColumns(vvv, _elemColumns);
264  blTris.clear();
265  blQuads.clear();
266  for(std::size_t i = 0; i < vvv.size(); i++) {
267  if(vvv[i]->getType() == TYPE_TRI)
268  blTris.push_back((MTriangle *)vvv[i]);
269  else if(vvv[i]->getType() == TYPE_QUA)
270  blQuads.push_back((MQuadrangle *)vvv[i]);
271  }
272 }
filterElements.h
MTriangle.h
MEdge
Definition: MEdge.h:14
MAX
#define MAX(a, b)
Definition: libol1.c:81
robustPredicates.h
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
MVertex
Definition: MVertex.h:24
MElement::getDim
virtual int getDim() const =0
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
intersectEdge2d
bool intersectEdge2d(const MEdge &ed1, const MEdge &ed2)
Definition: filterElements.cpp:73
SVector3
Definition: SVector3.h:16
TYPE_TRI
#define TYPE_TRI
Definition: GmshDefines.h:66
MElementBB
void MElementBB(void *a, double *min, double *max)
Definition: MElementOctree.cpp:17
MLine.h
rtree.h
MElement::getEdge
virtual MEdge getEdge(int num) const =0
RTree
Definition: rtree.h:100
MEdge::getVertex
MVertex * getVertex(std::size_t i) const
Definition: MEdge.h:39
pe2
const double pe2
Definition: GaussQuadratureQuad.cpp:76
MElement_Wrapper
Definition: filterElements.cpp:21
ElementType::getType
int getType(int parentType, int order, bool serendip=false)
Definition: ElementType.cpp:757
Less_Partition
Definition: filterElements.cpp:176
GmshDefines.h
MElement_Wrapper::_overlap
bool _overlap
Definition: filterElements.cpp:22
MElement
Definition: MElement.h:30
MElement_Wrapper::_notOverlap
std::vector< MElement * > _notOverlap
Definition: filterElements.cpp:24
MElement_Wrapper::MElement_Wrapper
MElement_Wrapper(MElement *e, const std::vector< MElement * > &notOverlap)
Definition: filterElements.cpp:25
overlap2D
bool overlap2D(MElement *e1, MElement *e2)
Definition: filterElements.cpp:131
SVector3::x
double x(void) const
Definition: SVector3.h:30
RTree::Insert
void Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE &a_dataId)
filterOverlappingElements
static void filterOverlappingElements(std::vector< MLine * > &lines, std::vector< MElement * > &els, std::map< MElement *, std::vector< MElement * > > &_elemColumns, std::map< MElement *, MElement * > &_toFirst)
Definition: filterElements.cpp:215
filterColumns
void filterColumns(std::vector< MElement * > &elem, std::map< MElement *, std::vector< MElement * > > &_elemColumns)
Definition: filterElements.cpp:183
MTriangle
Definition: MTriangle.h:26
TYPE_QUA
#define TYPE_QUA
Definition: GmshDefines.h:67
orientationTest
double orientationTest(double a[2], double b[2], double c[2])
Definition: filterElements.cpp:51
Less_Partition::operator()
bool operator()(const MElement *f1, const MElement *f2) const
Definition: filterElements.cpp:177
RTree::Search
int Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], bool a_resultCallback(DATATYPE a_data, void *a_context), void *a_context)
SVector3::y
double y(void) const
Definition: SVector3.h:31
MQuadrangle.h
MElement.h
rtree_callback
bool rtree_callback(MElement *e1, void *pe2)
Definition: filterElements.cpp:152
MElement_Wrapper::_e
MElement * _e
Definition: filterElements.cpp:23
MVertex::y
double y() const
Definition: MVertex.h:61
MElement::getPartition
virtual int getPartition() const
Definition: MElement.h:92
MElementInEle
int MElementInEle(void *a, double *x)
Definition: MElementOctree.cpp:84
MElement::getNumEdges
virtual int getNumEdges() const =0
MQuadrangle
Definition: MQuadrangle.h:26
robustPredicates::orient2d
REAL orient2d(REAL *pa, REAL *pb, REAL *pc)
Definition: robustPredicates.cpp:1633
MVertex::x
double x() const
Definition: MVertex.h:60
elem
Definition: OctreeInternals.h:17