SUAPI-CppWrapper
C++WrapperforSketchUpCAPI
Material.cpp
1 //
2 // Material.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/Material.hpp"
32 
33 #include <cassert>
34 #include <stdexcept>
35 
36 #include "SUAPI-CppWrapper/String.hpp"
37 #include "SUAPI-CppWrapper/Color.hpp"
38 #include "SUAPI-CppWrapper/model/Texture.hpp"
39 
40 namespace CW {
41 
42 /**************************
43 * Static private methods **
44 ***************************/
45 
46 SUMaterialRef Material::create_material() {
47  SUMaterialRef material = SU_INVALID;
48  SUResult res = SUMaterialCreate(&material);
49  assert(res == SU_ERROR_NONE); _unused(res);
50  return material;
51 }
52 
53 
54 SUMaterialRef Material::copy_reference(const Material& other) {
55  if (other.m_attached || SUIsInvalid(other.m_entity)) {
56  return other.ref();
57  }
58  return create_material();;
59 }
60 
61 /*****************************
62 * Constructors / Destructor **
63 ****************************/
64 Material::Material():
65  Entity()
66 {}
67 
68 
69 Material::Material(SUMaterialRef material_ref, bool attached):
70  Entity(SUMaterialToEntity(material_ref), attached)
71 {}
72 
73 
74 Material::Material(const Material& other):
75  Entity(other, SUMaterialToEntity(copy_reference(other)))
76 {
77  // Copy across properties of the other material
78  if (!other.m_attached && SUIsValid(m_entity)) {
79  this->name(other.name());
80  this->type(other.type());
81  this->opacity(other.opacity());
82  this->color(other.color());
83  this->texture(other.texture());
84  }
85 }
86 
87 
89  if (!m_attached && SUIsValid(m_entity)) {
90  SUMaterialRef material = this->ref();
91  SUResult res = SUMaterialRelease(&material);
92  assert(res == SU_ERROR_NONE); _unused(res);
93  }
94  m_entity = SUMaterialToEntity(copy_reference(other));
95 
96  if (!other.m_attached && SUIsValid(other.m_entity)) {
97  // The other material has not been attached to the model, so copy its properties to a new object
98  this->name(other.name());
99  this->type(other.type());
100  this->opacity(other.opacity());
101  this->color(other.color());
102  this->texture(other.texture());
103  }
104  Entity::operator=(other);
105  return *this;
106 }
107 
108 
110  if (!m_attached && SUIsValid(m_entity)) {
111  SUMaterialRef material = this->ref();
112  SUResult res = SUMaterialRelease(&material);
113  assert(res == SU_ERROR_NONE); _unused(res);
114  }
115 }
116 
117 
118 SUMaterialRef Material::ref() const {
119  return SUMaterialFromEntity(m_entity);
120 }
121 
122 
123 Material::operator SUMaterialRef() const {
124  return this->ref();
125 }
126 
127 bool Material::operator!() const {
128  if (SUIsInvalid(m_entity)) {
129  return true;
130  }
131  return false;
132 }
133 
135  if(!(*this)) {
136  throw std::logic_error("CW::Material::copy(): Material is null");
137  }
138  Material new_material(create_material(), false);
139  new_material.name(this->name());
140  new_material.type(this->type());
141  new_material.opacity(this->opacity());
142  new_material.color(this->color());
143  new_material.texture(this->texture());
144  new_material.copy_attributes_from((*this));
145  return new_material;
146 }
147 
148 
150  if (!(*this)) {
151  return Color();
152  }
153  SUColor new_color = SU_INVALID;
154  SUResult res = SUMaterialGetColor(this->ref(), &new_color);
155  if (res == SU_ERROR_NONE) {
156  return Color(new_color);
157  }
158  return Color();
159 }
160 
161 
163  if(!(*this)) {
164  throw std::logic_error("CW::Material::color(): Material is null");
165  }
166  SUColor set_color = color.ref();
167  SUResult res = SUMaterialSetColor(this->ref(), &set_color);
168  assert(res != SU_ERROR_INVALID_INPUT); _unused(res);
169 }
170 
171 
173  if (!(*this)) {
174  return String();
175  }
176  SUStringRef name_ref = SU_INVALID;
177  SUResult res = SUStringCreate(&name_ref);
178  assert(res == SU_ERROR_NONE);
179  res = SUMaterialGetName(this->ref(), &name_ref);
180  assert(res != SU_ERROR_INVALID_OUTPUT);
181  if (res == SU_ERROR_NONE) {
182  return String(name_ref);
183  }
184  else {
185  return String();
186  }
187 }
188 
189 
190 
192  if (!(*this)) {
193  return String();
194  }
195  SUStringRef name_ref = SU_INVALID;
196  SUResult res = SUStringCreate(&name_ref);
197  assert(res == SU_ERROR_NONE);
198  res = SUMaterialGetNameLegacyBehavior(this->ref(), &name_ref);
199  assert(res != SU_ERROR_INVALID_OUTPUT);
200  if (res == SU_ERROR_NONE) {
201  return String(name_ref);
202  }
203  else {
204  return String();
205  }
206 }
207 
208 void Material::name(const String& string) {
209  if(!(*this)) {
210  throw std::logic_error("CW::Material::name(): Material is null");
211  }
212  const char *cstr = string.std_string().c_str();
213  SUResult res = SUMaterialSetName(this->ref(), cstr);
214  assert(res == SU_ERROR_NONE); _unused(res);
215  return;
216 }
217 
218 
219 double Material::opacity() const {
220  if(!(*this)) {
221  throw std::logic_error("CW::Material::opacity(): Material is null");
222  }
223  double alpha;
224  SUResult res = SUMaterialGetOpacity(this->ref(), &alpha);
225  if (res == SU_ERROR_NONE) {
226  return alpha;
227  }
228  return 1.0;
229 }
230 
231 
232 void Material::opacity(const double alpha) {
233  if(!(*this)) {
234  throw std::logic_error("CW::Material::opacity(): Material is null");
235  }
236  double input_alpha = 1.0;
237  if (alpha > 1.0) {
238  input_alpha = 1.0;
239  }
240  else if (alpha < 0.0) {
241  input_alpha = 0.0;
242  }
243  SUResult res = SUMaterialSetOpacity(this->ref(), input_alpha);
244  assert(res != SU_ERROR_OUT_OF_RANGE); _unused(res);
245 }
246 
247 
249  if(!(*this)) {
250  throw std::logic_error("CW::Material::TEXTURE(): Material is null");
251  }
252  SUTextureRef get_texture = SU_INVALID;
253  SUResult res = SUMaterialGetTexture(this->ref(), &get_texture);
254  if (res != SU_ERROR_NONE) {
255  return Texture();
256  }
257  return Texture(get_texture);
258 }
259 
260 
262  if(!(*this)) {
263  throw std::logic_error("CW::Material::texture(): Material is null");
264  }
265  if (!texture) {
266  // no texture to apply
267  return;
268  }
269  if (texture.attached()) {
270  return this->texture(texture.copy());
271  }
272  SUTextureRef texture_ref = texture.ref();
273  SUResult res = SUMaterialSetTexture(this->ref(), texture_ref);
274  assert(res == SU_ERROR_NONE); _unused(res);
275 }
276 
277 
278 SUMaterialType Material::type() const {
279  if(!(*this)) {
280  throw std::logic_error("CW::Material::type(): Material is null");
281  }
282  SUMaterialType mat_type;
283  SUResult res = SUMaterialGetType(this->ref(), &mat_type);
284  assert(res == SU_ERROR_NONE); _unused(res);
285  return mat_type;
286 }
287 
288 
289 void Material::type(const SUMaterialType& material_type) {
290  if(!(*this)) {
291  throw std::logic_error("CW::Material::type(): Material is null");
292  }
293  SUResult res = SUMaterialSetType(this->ref(), material_type);
294  assert(res == SU_ERROR_NONE); _unused(res);
295 }
296 
297 
298 bool Material::use_alpha() const {
299  if(!(*this)) {
300  throw std::logic_error("CW::Material::use_alpha(): Material is null");
301  }
302  bool flag;
303  SUResult res = SUMaterialGetUseOpacity(this->ref(), &flag);
304  assert(res == SU_ERROR_NONE); _unused(res);
305  return flag;
306 }
307 
308 
309 void Material::use_alpha(bool flag) {
310  if(!(*this)) {
311  throw std::logic_error("CW::Material::use_alpha(): Material is null");
312  }
313  assert(!!(*this));
314  SUResult res = SUMaterialSetUseOpacity(this->ref(), flag);
315  assert(res == SU_ERROR_NONE); _unused(res);
316 }
317 
318 
319 
320 } /* namespace CW */
bool use_alpha() const
Definition: Material.cpp:298
bool m_attached
Indicates whether the Entity has been attached to a model.
Definition: Entity.hpp:64
Texture texture() const
Definition: Material.cpp:248
Material & operator=(const Material &other)
Definition: Material.cpp:88
Material copy() const
Definition: Material.cpp:134
Entity()
Constructor representing a null objject.
Definition: Entity.cpp:48
bool attached() const
Returns true if the entity is attached to another object.
Definition: Entity.cpp:100
bool copy_attributes_from(const Entity &entity)
Copies attributes from another Entity object to this one.
Definition: Entity.cpp:156
Texture copy() const
Definition: Texture.cpp:116
SUEntityRef m_entity
The C SUEntityRef that this class wraps.
Definition: Entity.hpp:59
double opacity() const
Definition: Material.cpp:219
Color color() const
Definition: Material.cpp:149
Definition: Color.hpp:34
bool operator!() const
Definition: Material.cpp:127
String display_name() const
Definition: Material.cpp:191
SUMaterialType type() const
Definition: Material.cpp:278
String name() const
Definition: Material.cpp:172
Entity & operator=(const Entity &other)
Copy assignment operator.
Definition: Entity.cpp:73