gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GEdgeLoop.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 <functional>
8 #include "GEdgeLoop.h"
9 #include "GmshMessage.h"
10 
11 void GEdgeSigned::print() const
12 {
13  if(getBeginVertex() && getEndVertex())
14  Msg::Info("Curve %d sign %d, begin point %d, end point %d", _ge->tag(),
15  _sign, getBeginVertex()->tag(), getEndVertex()->tag());
16  else
17  Msg::Info("Curve %d sign %d, no begin or end points", _ge->tag(), _sign);
18 }
19 
20 int countInList(std::list<GEdge *> &wire, GEdge *ge)
21 {
22  return std::count(wire.begin(), wire.end(), ge);
23 }
24 
25 GEdgeSigned nextOne(GEdgeSigned *thisOne, std::list<GEdge *> &wire)
26 {
27  if(!thisOne) {
28  GEdge *ge = *(wire.begin());
29  wire.erase(wire.begin());
30  return GEdgeSigned(1, ge);
31  }
32 
33  GVertex *gv = thisOne->getEndVertex();
34 
35  std::list<GEdge *> possibleChoices;
36 
37  auto it = wire.begin();
38  auto ite = wire.end();
39  while(it != ite) {
40  GEdge *ge = *it;
41  GVertex *v1 = ge->getBeginVertex();
42  GVertex *v2 = ge->getEndVertex();
43  if(v1 == gv || v2 == gv) possibleChoices.push_back(ge);
44  ++it;
45  }
46  it = possibleChoices.begin();
47  ite = possibleChoices.end();
48  while(it != ite) {
49  GEdge *ge = *it;
50  if(countInList(possibleChoices, ge) == 2) {
51  wire.erase(std::remove_if(wire.begin(), wire.end(),
52  std::bind2nd(std::equal_to<GEdge *>(), ge)),
53  wire.end());
54  wire.push_back(ge);
55  GVertex *v1 = ge->getBeginVertex();
56  GVertex *v2 = ge->getEndVertex();
57  if(v1 == gv) return GEdgeSigned(1, ge);
58  if(v2 == gv) return GEdgeSigned(-1, ge);
59  Msg::Error("Something wrong in curve loop 1");
60  thisOne->print();
61  }
62  ++it;
63  }
64  it = possibleChoices.begin();
65  ite = possibleChoices.end();
66  while(it != ite) {
67  GEdge *ge = *it;
68  if(ge != thisOne->getEdge()) {
69  wire.erase(std::remove_if(wire.begin(), wire.end(),
70  std::bind2nd(std::equal_to<GEdge *>(), ge)),
71  wire.end());
72  GVertex *v1 = ge->getBeginVertex();
73  GVertex *v2 = ge->getEndVertex();
74  if(v1 == gv) return GEdgeSigned(1, ge);
75  if(v2 == gv) return GEdgeSigned(-1, ge);
76  Msg::Error("Something wrong in curve loop 2");
77  thisOne->print();
78  }
79  ++it;
80  }
81 
82  // should never end up here
83  return GEdgeSigned(1, nullptr);
84 }
85 
86 int GEdgeLoop::count(GEdge *ge) const
87 {
88  int count = 0;
89  for(auto it = begin(); it != end(); ++it) {
90  if(it->getEdge() == ge) count++;
91  }
92  return count;
93 }
94 
95 void GEdgeLoop::print() const
96 {
97  for(auto it = begin(); it != end(); ++it) { it->print(); }
98 }
99 
100 void GEdgeLoop::getEdges(std::vector<GEdge *> &edges) const
101 {
102  edges.clear();
103  for(auto it = begin(); it != end(); ++it) { edges.push_back(it->getEdge()); }
104 }
105 
106 void GEdgeLoop::getSigns(std::vector<int> &signs) const
107 {
108  signs.clear();
109  for(auto it = begin(); it != end(); ++it) { signs.push_back(it->getSign()); }
110 }
111 
112 static void loopTheLoop(std::list<GEdge *> &wire, std::list<GEdgeSigned> &loop,
113  GEdge **degeneratedToInsert)
114 {
115  GEdgeSigned *prevOne = nullptr;
116  GEdgeSigned ges(1, nullptr);
117 
118  while(wire.size()) {
119  if(prevOne && (*degeneratedToInsert) &&
120  (*degeneratedToInsert)->getBeginVertex() == prevOne->getEndVertex()) {
121  ges = GEdgeSigned(1, *degeneratedToInsert);
122  *degeneratedToInsert = nullptr;
123  // printf("second degenerated edge inserted\n");
124  }
125  else
126  ges = nextOne(prevOne, wire);
127  if(!ges.getEdge()) { // oops
128  Msg::Debug("Could not find next curve in loop, aborting");
129  break;
130  }
131  prevOne = &ges;
132  // ges.print();
133  loop.push_back(ges);
134  }
135 }
136 
137 void GEdgeLoop::recompute(const std::vector<GEdge *> &cwire)
138 {
139  loop.clear();
140 #if 0
141  // Sometimes OCC puts a degenerated edge in the middle of the wire: this
142  // pushes it to front. This "fix" should not be necessary anymore.
143  std::list<GEdge *> wire;
144  std::vector<GEdge *> degenerated;
145  GEdge *degeneratedToInsert = nullptr;
146  for(auto it = cwire.begin(); it != cwire.end(); ++it) {
147  GEdge *ed = *it;
148  if(ed->degenerate(0))
149  degenerated.push_back(ed);
150  else
151  wire.push_back(ed);
152  }
153 
154  if(degenerated.size() == 1) { wire.push_front(degenerated[0]); }
155  else if(degenerated.size() == 2) {
156  degeneratedToInsert = degenerated[1];
157  wire.push_front(degenerated[0]);
158  }
159  else if(degenerated.size() > 2) {
160  Msg::Warning(
161  "More than two degenerated edges in one model face of an OCC model");
162  }
163 #else
164  std::list<GEdge *> wire(cwire.begin(), cwire.end());
165  GEdge *degeneratedToInsert = nullptr;
166 #endif
167 
168  while(!wire.empty()) { loopTheLoop(wire, loop, &degeneratedToInsert); }
169 }
170 
171 GEdgeLoop::GEdgeLoop(const std::vector<GEdge *> &wire)
172 {
173  recompute(wire);
174 }
175 
177 {
178  if(loop.empty()) return true;
179  std::vector<GEdgeSigned> all(begin(), end());
180  for(std::size_t i = 1; i < all.size(); i++) {
181  if(all[i - 1].getEndVertex() != all[i].getBeginVertex())
182  return false;
183  }
184  if(all.back().getEndVertex() != all.front().getBeginVertex())
185  return false;
186  return true;
187 }
188 
190 {
191  std::reverse(loop.begin(), loop.end());
192  for(auto es : loop) es.changeSign();
193 }
GEdgeLoop::GEdgeLoop
GEdgeLoop()
Definition: GEdgeLoop.h:43
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GEntity::degenerate
virtual bool degenerate(int dim) const
Definition: GEntity.h:248
GEdgeSigned::getBeginVertex
GVertex * getBeginVertex() const
Definition: GEdgeLoop.h:22
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
GEdgeSigned::getEndVertex
GVertex * getEndVertex() const
Definition: GEdgeLoop.h:26
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
GEdgeLoop::getEdges
void getEdges(std::vector< GEdge * > &edges) const
Definition: GEdgeLoop.cpp:100
GEdgeLoop.h
GEdgeLoop::begin
iter begin()
Definition: GEdgeLoop.h:48
GEdgeLoop::loop
std::list< GEdgeSigned > loop
Definition: GEdgeLoop.h:38
GmshMessage.h
edges
static int edges[6][2]
Definition: meshGRegionLocalMeshMod.cpp:23
GEdgeLoop::recompute
void recompute(const std::vector< GEdge * > &wire)
Definition: GEdgeLoop.cpp:137
GEdgeLoop::print
void print() const
Definition: GEdgeLoop.cpp:95
GVertex
Definition: GVertex.h:23
GEdgeLoop::reverse
void reverse()
Definition: GEdgeLoop.cpp:189
countInList
int countInList(std::list< GEdge * > &wire, GEdge *ge)
Definition: GEdgeLoop.cpp:20
GEdgeSigned::getEdge
GEdge * getEdge() const
Definition: GEdgeLoop.h:32
GEdge::getBeginVertex
virtual GVertex * getBeginVertex() const
Definition: GEdge.h:63
nextOne
GEdgeSigned nextOne(GEdgeSigned *thisOne, std::list< GEdge * > &wire)
Definition: GEdgeLoop.cpp:25
GEdgeSigned
Definition: GEdgeLoop.h:12
GEntity::tag
int tag() const
Definition: GEntity.h:280
GEdgeSigned::_sign
int _sign
Definition: GEdgeLoop.h:14
GEdgeLoop::count
int count() const
Definition: GEdgeLoop.h:54
GEdge
Definition: GEdge.h:26
GEdgeSigned::print
void print() const
Definition: GEdgeLoop.cpp:11
GEdge::getEndVertex
virtual GVertex * getEndVertex() const
Definition: GEdge.h:64
GEdgeSigned::_ge
GEdge * _ge
Definition: GEdgeLoop.h:15
GEdgeLoop::end
iter end()
Definition: GEdgeLoop.h:49
loopTheLoop
static void loopTheLoop(std::list< GEdge * > &wire, std::list< GEdgeSigned > &loop, GEdge **degeneratedToInsert)
Definition: GEdgeLoop.cpp:112
GEdgeLoop::check
bool check()
Definition: GEdgeLoop.cpp:176
GEdgeLoop::getSigns
void getSigns(std::vector< int > &signs) const
Definition: GEdgeLoop.cpp:106