gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
gmshEdgeDiscretize.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 <cstdio>
7 #include <cmath>
8 #include <vector>
9 #include "SPoint3.h"
10 #include "SVector3.h"
11 #include "GEdge.h"
12 #include "gmshEdge.h"
13 #include "Geo.h"
14 
15 class discreteList {
16  std::vector<std::pair<SPoint3, double> > _pts;
17  std::vector<int> _next;
18 
19 public:
20  int insertPoint(int pos, const SPoint3 &pt, double t)
21  {
22  _pts.push_back(std::make_pair(pt, t));
23  _next.push_back(_next[pos + 1]);
24  _next[pos + 1] = _pts.size() - 1;
25  return _pts.size() - 1;
26  }
27  void sort(std::vector<SPoint3> &spts, std::vector<double> &ts)
28  {
29  spts.clear();
30  spts.reserve(_pts.size());
31  ts.clear();
32  ts.reserve(_pts.size());
33  for(int p = _next[0]; p != -1; p = _next[p + 1]) {
34  spts.push_back(_pts[p].first);
35  ts.push_back(_pts[p].second);
36  }
37  }
38  discreteList() { _next.push_back(-1); }
39 };
40 
41 static void decasteljau(double tol, discreteList &discrete, int pos,
42  const SPoint3 &p0, const SPoint3 &p1, const SPoint3 &p2,
43  const SPoint3 &p3, double t0, double t3)
44 {
45  SVector3 d30 = p3 - p0;
46  SVector3 d13 = p1 - p3;
47  SVector3 d23 = p2 - p3;
48  SVector3 d130 = crossprod(d13, d30);
49  SVector3 d230 = crossprod(d23, d30);
50  double d = std::max(dot(d130, d130), dot(d230, d230));
51  double l2 = dot(d30, d30);
52 
53  if(d < tol * tol * l2) { return; }
54 
55  SPoint3 p01((p0 + p1) * 0.5);
56  SPoint3 p12((p1 + p2) * 0.5);
57  SPoint3 p23((p2 + p3) * 0.5);
58  SPoint3 p012((p01 + p12) * 0.5);
59  SPoint3 p123((p12 + p23) * 0.5);
60  SPoint3 p0123((p012 + p123) * 0.5);
61  double t0123 = 0.5 * (t0 + t3);
62  int newpos = discrete.insertPoint(pos, p0123, t0123);
63 
64  decasteljau(tol, discrete, pos, p0, p01, p012, p0123, t0, t0123);
65  decasteljau(tol, discrete, newpos, p0123, p123, p23, p3, t0123, t3);
66 }
67 
68 static int discretizeBezier(double tol, discreteList &discrete, int pos,
69  const SPoint3 pt[4], double t0, double t3,
70  bool insertFirstPoint)
71 {
72  if(insertFirstPoint) pos = discrete.insertPoint(pos, pt[0], t0);
73  int newp = discrete.insertPoint(pos, pt[3], t3);
74  decasteljau(tol, discrete, pos, pt[0], pt[1], pt[2], pt[3], t0, t3);
75  return newp;
76 }
77 
78 static int discretizeBSpline(double tol, discreteList &discrete, int pos,
79  const SPoint3 pt[4], double t0, double t3,
80  bool insertFirstPoint)
81 {
82  SPoint3 bpt[4] = {SPoint3((pt[0] + 4 * pt[1] + pt[2]) * (1. / 6.)),
83  SPoint3((2 * pt[1] + pt[2]) * (1. / 3.)),
84  SPoint3((pt[1] + 2 * pt[2]) * (1. / 3.)),
85  SPoint3((pt[1] + 4 * pt[2] + pt[3]) * (1. / 6.))};
86  return discretizeBezier(tol, discrete, pos, bpt, t0, t3, insertFirstPoint);
87 }
88 
89 static int discretizeCatmullRom(double tol, discreteList &discrete, int pos,
90  const SPoint3 pt[4], double t0, double t3,
91  bool insertFirstPoint)
92 {
93  SPoint3 bpt[4] = {pt[1], SPoint3((6 * pt[1] + pt[2] - pt[0]) * (1. / 6.)),
94  SPoint3((6 * pt[2] - pt[3] + pt[1]) * (1. / 6.)), pt[2]};
95  return discretizeBezier(tol, discrete, pos, bpt, t0, t3, insertFirstPoint);
96 }
97 
98 static inline SPoint3 curveGetPoint(Curve *c, int i)
99 {
100  Vertex *v;
101  List_Read(c->Control_Points, i, &v);
102  return SPoint3(v->Pos.X, v->Pos.Y, v->Pos.Z);
103 }
104 
105 static void discretizeCurve(Curve *c, double tol, std::vector<SPoint3> &pts,
106  std::vector<double> &ts)
107 {
108  discreteList discrete;
109  switch(c->Typ) {
110  case MSH_SEGM_LINE: {
111  int NPt = List_Nbr(c->Control_Points);
112  pts.resize(NPt);
113  ts.resize(NPt);
114  for(int i = 0; i < NPt; ++i) {
115  pts[i] = curveGetPoint(c, i);
116  ts[i] = i / (double)(NPt - 1);
117  }
118  return;
119  }
120  case MSH_SEGM_BEZIER: {
121  int back = -1;
122  int NbCurves = (List_Nbr(c->Control_Points) - 1) / 3;
123  for(int iCurve = 0; iCurve < NbCurves; ++iCurve) {
124  double t1 = (iCurve) / (double)(NbCurves);
125  double t2 = (iCurve + 1) / (double)(NbCurves);
126  SPoint3 pt[4];
127  for(int i = 0; i < 4; i++) { pt[i] = curveGetPoint(c, iCurve * 3 + i); }
128  back = discretizeBezier(tol, discrete, back, pt, t1, t2, iCurve == 0);
129  }
130  break;
131  }
132  case MSH_SEGM_BSPLN: {
133  int back = -1;
134  bool periodic = (c->end == c->beg);
135  int NbControlPoints = List_Nbr(c->Control_Points);
136  int NbCurves = NbControlPoints + (periodic ? -1 : 1);
137  SPoint3 pt[4];
138  for(int iCurve = 0; iCurve < NbCurves; ++iCurve) {
139  double t1 = (iCurve) / (double)(NbCurves);
140  double t2 = (iCurve + 1) / (double)(NbCurves);
141  for(int i = 0; i < 4; i++) {
142  int k;
143  if(periodic) {
144  k = (iCurve - 1 + i) % (NbControlPoints - 1);
145  if(k < 0) k += NbControlPoints - 1;
146  }
147  else {
148  k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints - 1));
149  }
150  pt[i] = curveGetPoint(c, k);
151  }
152  back = discretizeBSpline(tol, discrete, back, pt, t1, t2, iCurve == 0);
153  }
154  break;
155  }
156  case MSH_SEGM_SPLN: {
157  int NbCurves = List_Nbr(c->Control_Points) - 1;
158  SPoint3 pt[4];
159  int back = -1;
160  for(int iCurve = 0; iCurve < NbCurves; ++iCurve) {
161  double t1 = (iCurve) / (double)(NbCurves);
162  double t2 = (iCurve + 1) / (double)(NbCurves);
163  pt[1] = curveGetPoint(c, iCurve);
164  pt[2] = curveGetPoint(c, iCurve + 1);
165  if(iCurve == 0) {
166  if(c->beg == c->end)
167  pt[0] = curveGetPoint(c, NbCurves - 1);
168  else
169  pt[0] = SPoint3(pt[1] * 2 - pt[2]);
170  }
171  else
172  pt[0] = curveGetPoint(c, iCurve - 1);
173  if(iCurve == NbCurves - 1) {
174  if(c->beg == c->end)
175  pt[3] = curveGetPoint(c, 1);
176  else
177  pt[3] = SPoint3(2 * pt[2] - pt[1]);
178  }
179  else
180  pt[3] = curveGetPoint(c, iCurve + 2);
181  back = discretizeCatmullRom(tol, discrete, back, pt, t1, t2, iCurve == 0);
182  }
183  break;
184  }
185  default:
186  Msg::Error("discretizeCurve not implemented for curve type %d", c->Typ);
187  }
188  discrete.sort(pts, ts);
189 }
190 
191 void gmshEdge::discretize(double tol, std::vector<SPoint3> &dpts,
192  std::vector<double> &ts)
193 {
194  discretizeCurve(c, tol, dpts, ts);
195 }
crossprod
SVector3 crossprod(const SVector3 &a, const SVector3 &b)
Definition: SVector3.h:150
Geo.h
MSH_SEGM_BEZIER
#define MSH_SEGM_BEZIER
Definition: GeoDefines.h:29
dot
double dot(const SVector3 &a, const SMetric3 &m, const SVector3 &b)
Definition: STensor3.h:71
gmshEdge.h
discretizeBSpline
static int discretizeBSpline(double tol, discreteList &discrete, int pos, const SPoint3 pt[4], double t0, double t3, bool insertFirstPoint)
Definition: gmshEdgeDiscretize.cpp:78
Curve
Definition: Geo.h:74
discretizeBezier
static int discretizeBezier(double tol, discreteList &discrete, int pos, const SPoint3 pt[4], double t0, double t3, bool insertFirstPoint)
Definition: gmshEdgeDiscretize.cpp:68
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
decasteljau
static void decasteljau(double tol, discreteList &discrete, int pos, const SPoint3 &p0, const SPoint3 &p1, const SPoint3 &p2, const SPoint3 &p3, double t0, double t3)
Definition: gmshEdgeDiscretize.cpp:41
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
SPoint3
Definition: SPoint3.h:14
List_Nbr
int List_Nbr(List_T *liste)
Definition: ListUtils.cpp:106
Vertex
Definition: Geo.h:29
discreteList::_pts
std::vector< std::pair< SPoint3, double > > _pts
Definition: gmshEdgeDiscretize.cpp:16
SVector3
Definition: SVector3.h:16
SVector3.h
MSH_SEGM_SPLN
#define MSH_SEGM_SPLN
Definition: GeoDefines.h:21
gmshEdge::discretize
virtual void discretize(double tol, std::vector< SPoint3 > &dpts, std::vector< double > &ts)
Definition: gmshEdge.cpp:539
discreteList::insertPoint
int insertPoint(int pos, const SPoint3 &pt, double t)
Definition: gmshEdgeDiscretize.cpp:20
GEdge.h
discreteList::discreteList
discreteList()
Definition: gmshEdgeDiscretize.cpp:38
discreteList
Definition: gmshEdgeDiscretize.cpp:15
discreteList::_next
std::vector< int > _next
Definition: gmshEdgeDiscretize.cpp:17
curveGetPoint
static SPoint3 curveGetPoint(Curve *c, int i)
Definition: gmshEdgeDiscretize.cpp:98
discretizeCurve
static void discretizeCurve(Curve *c, double tol, std::vector< SPoint3 > &pts, std::vector< double > &ts)
Definition: gmshEdgeDiscretize.cpp:105
discreteList::sort
void sort(std::vector< SPoint3 > &spts, std::vector< double > &ts)
Definition: gmshEdgeDiscretize.cpp:27
Coord::X
double X
Definition: Geo.h:26
discretizeCatmullRom
static int discretizeCatmullRom(double tol, discreteList &discrete, int pos, const SPoint3 pt[4], double t0, double t3, bool insertFirstPoint)
Definition: gmshEdgeDiscretize.cpp:89
Coord::Z
double Z
Definition: Geo.h:26
MSH_SEGM_BSPLN
#define MSH_SEGM_BSPLN
Definition: GeoDefines.h:27
Coord::Y
double Y
Definition: Geo.h:26
Vertex::Pos
Coord Pos
Definition: Geo.h:34
SPoint3.h
List_Read
void List_Read(List_T *liste, int index, void *data)
Definition: ListUtils.cpp:111
MSH_SEGM_LINE
#define MSH_SEGM_LINE
Definition: GeoDefines.h:20