SUAPI-CppWrapper
C++WrapperforSketchUpCAPI
ComponentDefinition.cpp
1 //
2 // ComponentDefinition.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 <cassert>
32 
33 #include "SUAPI-CppWrapper/model/ComponentDefinition.hpp"
34 #include "SUAPI-CppWrapper/model/Entities.hpp"
35 #include "SUAPI-CppWrapper/model/ComponentInstance.hpp"
36 #include "SUAPI-CppWrapper/model/Group.hpp"
37 #include "SUAPI-CppWrapper/model/Model.hpp"
38 #include "SUAPI-CppWrapper/model/Opening.hpp"
39 
40 namespace CW {
41 
42 /******************************
43 ** Private Static Methods **
44 *******************************/
45 SUComponentDefinitionRef ComponentDefinition::create_definition() {
46  SUComponentDefinitionRef definition = SU_INVALID;
47  SUResult res = SUComponentDefinitionCreate(&definition);
48  assert(res == SU_ERROR_NONE); _unused(res);
49  return definition;
50 }
51 
52 SUComponentDefinitionRef ComponentDefinition::copy_reference(const ComponentDefinition& other) {
53  if (other.m_attached && SUIsValid(other.m_entity)) {
54  return other.ref();
55  }
56  // The other definition has not been attached to the model, so copy its properties to a new object
57  SUComponentDefinitionRef new_definition = create_definition();
58  if (SUIsValid(other.m_entity)) {
59  // Copy across all nested geometry
60  SUEntitiesRef new_entities_ref = SU_INVALID;
61  SUResult res = SUComponentDefinitionGetEntities(new_definition, &new_entities_ref);
62  assert(res == SU_ERROR_NONE); _unused(res);
63  Entities new_entities(new_entities_ref, other.model().ref());
64  new_entities.add(other.entities());
65  }
66  return new_definition;
67 }
68 
69 
70 /******************************
71 ** Constructors / Destructor **
72 *******************************/
74  ComponentDefinition(create_definition(), true)
75 {
76 }
77 
78 
79 ComponentDefinition::ComponentDefinition(SUComponentDefinitionRef definition, bool attached):
80  DrawingElement(SUComponentDefinitionToDrawingElement(definition), attached)
81 {}
82 
83 
84 /**
85 * Copy constructor.
86 */
88  DrawingElement(SUComponentDefinitionToDrawingElement(copy_reference(other)))
89 {}
90 
91 
93  if (!m_attached && SUIsValid(m_entity)) {
94  SUComponentDefinitionRef definition = this->ref();
95  SUComponentDefinitionRelease(&definition);
96  }
97 }
98 
99 
100 /**
101 * Copy assignment operator.
102 */
104  if (!m_attached && SUIsValid(m_entity)) {
105  SUComponentDefinitionRef definition = this->ref();
106  SUResult res = SUComponentDefinitionRelease(&definition);
107  assert(res == SU_ERROR_NONE); _unused(res);
108  }
109  m_entity = SUComponentDefinitionToEntity(copy_reference(other));
110  // Copy across all ComponentDefinition properties
111  this->name(other.name());
112  this->behavior(other.behavior());
114  return *this;
115 }
116 
117 
118 SUComponentDefinitionRef ComponentDefinition::ref() const {
119  return SUComponentDefinitionFromEntity(m_entity);
120 }
121 
122 
123 ComponentDefinition::operator SUComponentDefinitionRef() const {
124  return this->ref();
125 }
126 
127 
129  if (!(*this)) {
130  throw std::logic_error("CW::ComponentDefinition::create_instance(): ComponentDefinition is null");
131  }
132  SUComponentInstanceRef instance = SU_INVALID;
133  SUResult res = SUComponentDefinitionCreateInstance(this->ref(), &instance);
134  assert(res == SU_ERROR_NONE); _unused(res);
135  return ComponentInstance(instance, false);
136 }
137 
138 /*
139 Group ComponentDefinition::create_group() const {
140  assert(this->is_group());
141  SUComponentInstanceRef instance = SU_INVALID;
142  SUResult res = SUComponentDefinitionCreateInstance(m_definition, &instance);
143  assert(res == SU_ERROR_NONE); _unused(res);
144  SUGroupRef group = SUGroupFromComponentInstance(instance);
145  return Group(group, false);
146 }
147 */
148 
149 
151  if (!(*this)) {
152  throw std::logic_error("CW::ComponentDefinition::entities(): ComponentDefinition is null");
153  }
154  SUEntitiesRef entities = SU_INVALID;
155  SUResult res = SUComponentDefinitionGetEntities(this->ref(), &entities);
156  assert(res == SU_ERROR_NONE); _unused(res);
157  return Entities(entities, this->model().ref());
158 }
159 
160 
162  if (!(*this)) {
163  throw std::logic_error("CW::ComponentDefinition::name(): ComponentDefinition is null");
164  }
165  SUStringRef name_string = SU_INVALID;
166  SUResult res = SUStringCreate(&name_string);
167  assert(res == SU_ERROR_NONE);
168  res = SUComponentDefinitionGetName(this->ref(), &name_string);
169  assert(res == SU_ERROR_NONE); _unused(res);
170  return String(name_string);
171 }
172 
173 
175  if (!(*this)) {
176  throw std::logic_error("CW::ComponentDefinition::name(): ComponentDefinition is null");
177  }
178  SUResult res = SUComponentDefinitionSetName(this->ref(), std::string(name).c_str());
179  if (res == SU_ERROR_NONE) {
180  return true;
181  }
182  return false;
183 }
184 
185 
187  if (!(*this)) {
188  throw std::logic_error("CW::ComponentDefinition::is_group(): ComponentDefinition is null");
189  }
190  SUComponentType type;
191  SUResult res = SUComponentDefinitionGetType(this->ref(), &type);
192  assert(res == SU_ERROR_NONE); _unused(res);
193  if (type == SUComponentType_Group) {
194  return true;
195  }
196  else {
197  return false;
198  }
199 }
200 
201 
203  if (!(*this)) {
204  throw std::logic_error("CW::ComponentDefinition::behavior(): ComponentDefinition is null");
205  }
206  SUComponentBehavior behavior;
207  SUResult res = SUComponentDefinitionGetBehavior(this->ref(), &behavior);
208  assert(res == SU_ERROR_NONE); _unused(res);
209  return Behavior(behavior);
210 }
211 
213  if (!(*this)) {
214  throw std::logic_error("CW::ComponentDefinition::behavior(): ComponentDefinition is null");
215  }
216  SUComponentBehavior behavior_ref = behavior.ref();
217  SUResult res = SUComponentDefinitionSetBehavior(this->ref(), &behavior_ref);
218  assert(res == SU_ERROR_NONE); _unused(res);
219 }
220 
221 
223  size_t num = 0;
224  SUResult res = SUComponentDefinitionGetNumUsedInstances(this->ref(), &num);
225  assert(res == SU_ERROR_NONE); _unused(res);
226  return num;
227 }
228 
229 
231  size_t num = 0;
232  SUResult res = SUComponentDefinitionGetNumInstances(this->ref(), &num);
233  assert(res == SU_ERROR_NONE); _unused(res);
234  return num;
235 }
236 
237 
238 std::vector<ComponentInstance> ComponentDefinition::instances() const {
239  if (!SUIsValid(this->ref())) {
240  throw std::logic_error("CW::ComponentDefinition::instances(): definition is null");
241  }
242  size_t count = this->num_instances();
243  if (count == 0) {
244  return std::vector<ComponentInstance>{};
245  }
246  std::vector<SUComponentInstanceRef> instance_refs(count, SU_INVALID);
247  SUResult res = SUComponentDefinitionGetInstances(this->ref(), count, instance_refs.data(), &count);
248  assert(res == SU_ERROR_NONE); _unused(res);
249  std::vector<ComponentInstance> instances(count);
250  std::transform(instance_refs.begin(), instance_refs.end(), instances.begin(),
251  [](const SUComponentInstanceRef& value) {
252  return ComponentInstance(value);
253  });;
254  return instances;
255 }
256 
257 
259  if (!(*this)) {
260  throw std::logic_error("CW::ComponentDefinition::num_openings(): ComponentDefinition is null");
261  }
262  size_t count = 0;
263  SU_RESULT res = SUComponentDefinitionGetNumOpenings(this->ref(), &count);
264  assert(res == SU_ERROR_NONE); _unused(res);
265  return count;
266 }
267 
268 
269 std::vector<Opening> ComponentDefinition::openings() const {
270  if (!(*this)) {
271  throw std::logic_error("CW::ComponentDefinition::num_openings(): ComponentDefinition is null");
272  }
273  size_t count = this->num_openings();
274  std::vector<SUOpeningRef> opening_refs(count, SU_INVALID);
275  size_t return_count = 0;
276  SU_RESULT res = SUComponentDefinitionGetOpenings(this->ref(), count, opening_refs.data(), &return_count);
277  assert(return_count == count);
278  assert(res == SU_ERROR_NONE); _unused(res);
279  std::vector<Opening> openings;
280  openings.reserve(return_count);
281  for (SUOpeningRef p : opening_refs) {
282  openings.push_back(Opening(p));
283  }
284  return openings;
285 }
286 
287 
288 /****************
289 * Behavior class
290 *****************/
291 
292 Behavior::Behavior(SUComponentBehavior behavior):
293 m_behavior(behavior)
294 {
295 }
296 
297 SUComponentBehavior Behavior::ref() const {
298  return m_behavior;
299 }
300 
301 
302 } /* namespace CW */
bool m_attached
Indicates whether the Entity has been attached to a model.
Definition: Entity.hpp:64
ComponentInstance create_instance() const
SUComponentDefinitionRef ref() const
std::vector< Opening > openings() const
bool attached() const
Returns true if the entity is attached to another object.
Definition: Entity.cpp:100
DrawingElement & operator=(const DrawingElement &other)
Model model() const
Definition: Entity.cpp:241
SUEntityRef m_entity
The C SUEntityRef that this class wraps.
Definition: Entity.hpp:59
Definition: Color.hpp:34
ComponentDefinition & operator=(const ComponentDefinition &other)
std::vector< ComponentInstance > instances() const