SUAPI-CppWrapper
C++WrapperforSketchUpCAPI
Edge.cpp
1 //
2 // Edge.cpp
3 //
4 // Sketchup C++ Wrapper for C API
5 // MIT License
6 //
7 // Copyright (c) 2017 Tom Kaneko
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 
16 // The above copyright notice and this permission notice shall be included in all
17 // copies or substantial portions of the Software.
18 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 // SOFTWARE.
26 //
27 
28 // Macro for getting rid of unused variables commonly for assert checking
29 #define _unused(x) ((void)(x))
30 
31 #include "SUAPI-CppWrapper/model/Edge.hpp"
32 
33 #include <cassert>
34 #include <stdexcept>
35 
36 #include "SUAPI-CppWrapper/Color.hpp"
37 #include "SUAPI-CppWrapper/model/Vertex.hpp"
38 #include "SUAPI-CppWrapper/model/Face.hpp"
39 
40 namespace CW {
41 /**************************
42 * Private static methods **
43 ***************************/
44 SUEdgeRef Edge::create_edge(const Point3D& start, const Point3D& end) {
45  if (!start || !end) {
46  throw std::invalid_argument("CW::Edge::create_edge(): given Point3D is null");
47  }
48  if (start == end) {
49  throw std::invalid_argument("CW::Edge::create_edge(): start and end points are equal - cannot create edge of zero length");
50  }
51  SUEdgeRef edge = SU_INVALID;
52  SUPoint3D start_ref = start;
53  SUPoint3D end_ref = end;
54  SUResult res = SUEdgeCreate(&edge, &start_ref, &end_ref);
55  assert(res == SU_ERROR_NONE); _unused(res);
56  return edge;
57 }
58 
59 
60 SUEdgeRef Edge::copy_reference(const Edge& other) {
61  if (other.m_attached) {
62  return other.ref();
63  }
64  SUEdgeRef new_edge = create_edge(other.start().position(), other.end().position());
65  return new_edge;
66 }
67 
68 /*****************************
69 * Constructors / Destructor **
70 ******************************/
72  DrawingElement(SU_INVALID, true)
73 {}
74 
75 
76 Edge::Edge(const std::vector<Point3D>& points):
77  Edge(create_edge(points[0], points[1]), false)
78 {}
79 
80 
81 Edge::Edge(const Point3D& start, const Point3D& end):
82  Edge(create_edge(start, end), false)
83 {}
84 
85 
86 Edge::Edge(const Vertex& start, const Vertex& end):
87  Edge(start.position(), end.position())
88 {}
89 
90 
91 Edge::Edge(SUEdgeRef edge, bool attached):
92  DrawingElement(SUEdgeToDrawingElement(edge), attached)
93 {}
94 
95 
96 Edge::Edge(const Edge& other):
97  DrawingElement(other, SUEdgeToDrawingElement(copy_reference(other)))
98 {
99  if (!other.m_attached && SUIsValid(other.ref())) {
100  this->color(other.color());
101  this->smooth(other.smooth());
102  this->soft(other.soft());
103  }
104 }
105 
106 
107 Edge::~Edge() {
108  if (!m_attached && SUIsValid(m_entity)) {
109  SUEdgeRef edge = this->ref();
110  SUResult res = SUEdgeRelease(&edge);
111  assert(res == SU_ERROR_NONE); _unused(res);
112  }
113 }
114 
115 /******************
116 * Public Methods **
117 *******************/
118 Edge& Edge::operator=(const Edge& other) {
119  if (!m_attached && SUIsValid(m_entity)) {
120  SUEdgeRef edge = this->ref();
121  SUResult res = SUEdgeRelease(&edge);
122  assert(res == SU_ERROR_NONE); _unused(res);
123  }
124  m_entity = SUEdgeToEntity(copy_reference(other));
125  if (!other.m_attached) {
126  this->color(other.color());
127  this->smooth(other.smooth());
128  this->soft(other.soft());
129  }
131  return *this;
132 }
133 
134 
135 SUEdgeRef Edge::ref() const {
136  return SUEdgeFromEntity(m_entity);
137 }
138 
139 Edge::operator SUEdgeRef() const {
140  return this->ref();
141 }
142 
143 
144 bool Edge::operator!() const {
145  if (SUIsInvalid(m_entity)) {
146  return true;
147  }
148  return false;
149 }
150 
151 
152 Color Edge::color() const {
153  if (!(*this)) {
154  throw std::logic_error("CW::Edge::color(): Edge is null");
155  }
156  SUColor color = SU_INVALID;
157  SUEdgeGetColor(this->ref(), &color);
158  return Color(color);
159 }
160 
161 
162 bool Edge::color(const Color& input_color) {
163  if (!(*this)) {
164  throw std::logic_error("CW::Edge::color(): Edge is null");
165  }
166  SUColor color = input_color.ref();
167  SUResult result = SUEdgeSetColor(this->ref(), &color);
168  if (result == SU_ERROR_NONE) {
169  return true;
170  }
171  return false;
172 }
173 
174 
175 Vertex Edge::end() const {
176  if (!(*this)) {
177  throw std::logic_error("CW::Edge::end(): Edge is null");
178  }
179  SUVertexRef vertex = SU_INVALID;
180  SUEdgeGetEndVertex(this->ref(), &vertex);
181  return Vertex(vertex);
182 }
183 
184 
185 std::vector<Face> Edge::faces() const {
186  if (!(*this)) {
187  throw std::logic_error("CW::Edge::faces(): Edge is null");
188  }
189  size_t count = 0;
190  SUResult res = SUEdgeGetNumFaces(this->ref(), &count);
191  assert(res == SU_ERROR_NONE);
192  if (count == 0) {
193  return std::vector<Face>();
194  }
195  std::vector<SUFaceRef> face_refs(count, SU_INVALID);
196  res = SUEdgeGetFaces(this->ref(), count, face_refs.data(), &count);
197  assert(res == SU_ERROR_NONE); _unused(res);
198  std::vector<Face> faces(count);
199  std::transform(face_refs.begin(), face_refs.end(), faces.begin(),
200  [](const SUFaceRef& value) {
201  return Face(value);
202  });
203  return faces;
204 }
205 
206 Vector3D Edge::vector() const {
207  if (!(*this)) {
208  throw std::logic_error("CW::Edge::vector(): Edge is null");
209  }
210  return end().position() - start().position();
211 }
212 
213 
214 bool Edge::smooth() const {
215  if (!(*this)) {
216  throw std::logic_error("CW::Edge::smooth(): Edge is null");
217  }
218  bool smooth_flag;
219  SUEdgeGetSmooth(this->ref(), &smooth_flag);
220  return smooth_flag;
221 }
222 
223 
224 bool Edge::smooth(bool smooth) {
225  if (!(*this)) {
226  throw std::logic_error("CW::Edge::smooth(): Edge is null");
227  }
228  SUResult result = SUEdgeSetSmooth(this->ref(), smooth);
229  if (result == SU_ERROR_NONE) {
230  return true;
231  }
232  return false;
233 }
234 
235 
236 bool Edge::soft() const {
237  if (!(*this)) {
238  throw std::logic_error("CW::Edge::soft(): Edge is null");
239  }
240  bool soft_flag;
241  SUEdgeGetSoft(this->ref(), &soft_flag);
242  return soft_flag;
243 }
244 
245 
246 bool Edge::soft(bool soft) {
247  if (!(*this)) {
248  throw std::logic_error("CW::Edge::soft(): Edge is null");
249  }
250  SUResult result = SUEdgeSetSoft(this->ref(), soft);
251  if (result == SU_ERROR_NONE) {
252  return true;
253  }
254  return false;
255 }
256 
257 
258 Vertex Edge::start() const {
259  if (!(*this)) {
260  throw std::logic_error("CW::Edge::start(): Edge is null");
261  }
262  SUVertexRef vertex = SU_INVALID;
263  SUEdgeGetStartVertex(this->ref(), &vertex);
264  return Vertex(vertex);
265 }
266 
267 
268 } /* namespace CW */
bool m_attached
Indicates whether the Entity has been attached to a model.
Definition: Entity.hpp:64
bool operator!() const
Definition: Edge.cpp:144
bool attached() const
Returns true if the entity is attached to another object.
Definition: Entity.cpp:100
Edge()
Definition: Edge.cpp:71
DrawingElement & operator=(const DrawingElement &other)
SUEntityRef m_entity
The C SUEntityRef that this class wraps.
Definition: Entity.hpp:59
SUEdgeRef ref() const
Definition: Edge.cpp:135
Definition: Color.hpp:34