SUAPI-CppWrapper
C++WrapperforSketchUpCAPI
Texture.cpp
1 //
2 // Texture.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/Texture.hpp"
32 #include <cassert>
33 #include <stdexcept>
34 #include <stdio.h>
35 
36 #include "SUAPI-CppWrapper/model/ImageRep.hpp"
37 #include "SUAPI-CppWrapper/String.hpp"
38 
39 namespace CW {
40 /******************************
41 ** Private Static Methods *****
42 *******************************/
43 
44 SUTextureRef Texture::create_texture(ImageRep& image_rep) {
45  SUImageRepRef image = image_rep.ref();
46  SUTextureRef texture = SU_INVALID;
47  SUResult res = SUTextureCreateFromImageRep(&texture, image);
48  assert(res == SU_ERROR_NONE); _unused(res);
49  return texture;
50 }
51 
52 SUTextureRef Texture::create_texture(const std::string file_path, double s_scale, double t_scale) {
53  SUTextureRef texture = SU_INVALID;
54  SUResult res = SUTextureCreateFromFile(&texture, file_path.c_str(), s_scale,t_scale);
55  if (res != SU_ERROR_NONE) {
56  return SU_INVALID;
57  }
58  return texture;
59 }
60 
61 
62 SUTextureRef Texture::copy_reference(const Texture& other) {
63  return other.ref();
64 }
65 
66 /******************************
67 ** Constructors / Destructor **
68 *******************************/
70  Entity()
71 {}
72 
73 
74 Texture::Texture(SUTextureRef texture, bool attached):
75  Entity(SUTextureToEntity(texture), attached)
76 {}
77 
78 
79 Texture::Texture(const Texture& other):
80  Entity(other, SUTextureToEntity(copy_reference(other)))
81 {}
82 
83 
84 Texture::Texture(const std::string file_path, double s_scale, double t_scale):
85  Texture(create_texture(file_path, s_scale, t_scale), false)
86 {}
87 
88 
90  Texture(create_texture(image), false)
91 {}
92 
93 
95 }
96 
97 
99  // Simply assign the other texture to this object.
100  m_entity = SUTextureToEntity(other.ref());
101  Entity::operator=(other);
102  return (*this);
103 }
104 
105 
106 SUTextureRef Texture::ref() const {
107  return SUTextureFromEntity(m_entity);
108 }
109 
110 
111 Texture::operator SUTextureRef() const {
112  return this->ref();
113 }
114 
115 
117  // First create the file.
118  std::string file_path = "/tmp/tmptexture";
119  SUResult res = this->save(file_path);
120  assert(res == SU_ERROR_NONE); _unused(res);
121  Texture new_texture(file_path, s_scale(), t_scale());
122  // Delete the temporary file
123  const char *file_path_c = file_path.c_str();
124  int ret = std::remove(file_path_c);
125  assert(ret == 0); _unused(ret);
126  // Reset the file name
127  new_texture.file_name(this->file_name());
128  return new_texture;
129  // @developers_notes Method below is efficient and simple, but fails to transfer the scale of the texture, due to the lack of SUTextureSetDimensions() function in the C API. A workaround method is used for now shown above.
130  /*
131  ImageRep image_rep = this->image_rep().copy();
132  Texture new_texture(image_rep);
133  new_texture.file_name(this->file_name());
134  return new_texture;
135  */
136 }
137 
138 
139 bool Texture::alpha_used() const {
140  if (!(*this)) {
141  throw std::logic_error("CW::Texture::alpha_used(): Texture is null");
142  }
143  bool alpha_channel_used;
144  SUResult res = SUTextureGetUseAlphaChannel(this->ref(), &alpha_channel_used);
145  assert(res == SU_ERROR_NONE); _unused(res);
146  return alpha_channel_used;
147 }
148 
149 
151  if (!(*this)) {
152  throw std::logic_error("CW::Texture::alpha_used(): Texture is null");
153  }
154  SUImageRepRef image_rep = SU_INVALID;
155  SUResult res = SUImageRepCreate(&image_rep);
156  assert(res == SU_ERROR_NONE);
157  res = SUTextureGetImageRep(this->ref(), &image_rep);
158  assert(res == SU_ERROR_NONE); _unused(res);
159  return ImageRep(image_rep);
160 }
161 
162 
164  String name;
165  SUStringRef file_ref = name.ref();
166  SUResult res = SUTextureGetFileName(this->ref(), &file_ref);
167  assert(res == SU_ERROR_NONE); _unused(res);
168  return name;
169 }
170 
171 
172 void Texture::file_name(const String& string) const {
173  const char* chars = string.std_string().c_str();
174  SUResult res = SUTextureSetFileName(this->ref(), chars);
175  assert(res == SU_ERROR_NONE); _unused(res);
176 }
177 
178 
179 size_t Texture::width() const {
180  if (!(*this)) {
181  throw std::logic_error("CW::Texture::width(): Texture is null");
182  }
183  size_t width;
184  size_t height;
185  double s_scale;
186  double t_scale;
187  SUResult res = SUTextureGetDimensions(this->ref(), &width, &height, &s_scale, &t_scale);
188  assert(res == SU_ERROR_NONE); _unused(res);
189  return width;
190 }
191 
192 
193 size_t Texture::height() const {
194  if (!(*this)) {
195  throw std::logic_error("CW::Texture::height(): Texture is null");
196  }
197  size_t width;
198  size_t height;
199  double s_scale;
200  double t_scale;
201  SUResult res = SUTextureGetDimensions(this->ref(), &width, &height, &s_scale, &t_scale);
202  assert(res == SU_ERROR_NONE); _unused(res);
203  return height;
204 }
205 
206 
207 double Texture::s_scale() const {
208  if (!(*this)) {
209  throw std::logic_error("CW::Texture::s_scale(): Texture is null");
210  }
211  size_t width;
212  size_t height;
213  double s_scale;
214  double t_scale;
215  SUResult res = SUTextureGetDimensions(this->ref(), &width, &height, &s_scale, &t_scale);
216  assert(res == SU_ERROR_NONE); _unused(res);
217  return s_scale;
218 }
219 
220 
221 double Texture::t_scale() const {
222  if (!(*this)) {
223  throw std::logic_error("CW::Texture::t_scale(): Texture is null");
224  }
225  size_t width;
226  size_t height;
227  double s_scale;
228  double t_scale;
229  SUResult res = SUTextureGetDimensions(this->ref(), &width, &height, &s_scale, &t_scale);
230  assert(res == SU_ERROR_NONE); _unused(res);
231  return t_scale;
232 }
233 
234 
235 SUResult Texture::save(const std::string& file_path) const {
236  const char *cstr = file_path.c_str();
237  SUResult res = SUTextureWriteToFile(this->ref(), cstr);
238  return res;
239 }
240 
241 } /* namespace CW */
size_t height() const
Definition: Texture.cpp:193
bool attached() const
Returns true if the entity is attached to another object.
Definition: Entity.cpp:100
size_t width() const
Definition: Texture.cpp:179
Texture copy() const
Definition: Texture.cpp:116
SUEntityRef m_entity
The C SUEntityRef that this class wraps.
Definition: Entity.hpp:59
double s_scale() const
Definition: Texture.cpp:207
ImageRep image_rep() const
Definition: Texture.cpp:150
Definition: Color.hpp:34
Texture & operator=(const Texture &other)
Definition: Texture.cpp:98
bool alpha_used() const
Definition: Texture.cpp:139
String file_name() const
Definition: Texture.cpp:163
SUResult save(const std::string &file_path) const
Definition: Texture.cpp:235
double t_scale() const
Definition: Texture.cpp:221
Entity & operator=(const Entity &other)
Copy assignment operator.
Definition: Entity.cpp:73