SUAPI-CppWrapper
C++WrapperforSketchUpCAPI
ComponentInstance.cpp
1 //
2 // ComponentInstance.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/ComponentInstance.hpp"
34 
35 #include <SketchUpAPI/model/group.h>
36 
37 #include "SUAPI-CppWrapper/String.hpp"
38 
39 namespace CW {
40 
41 /**************************
42 * Private static methods **
43 ***************************/
44 
45 SUComponentInstanceRef ComponentInstance::copy_reference(const ComponentInstance& other) {
46  if (other.m_attached) {
47  return other.ref();
48  }
49  // The other face has not been attached to the model, so copy its properties to a new object
50  ComponentInstance new_instance = other.definition().create_instance();
51  new_instance.transformation(other.transformation());
52  new_instance.name(other.name());
53  return new_instance.ref();
54 }
55 
56 /*****************************
57 * Constructors / Destructor **
58 ******************************/
61 {}
62 
63 
64 ComponentInstance::ComponentInstance(SUComponentInstanceRef instance, bool attached):
65  DrawingElement(SUComponentInstanceToDrawingElement(instance), attached)
66 {}
67 
68 
70  DrawingElement(other, SUComponentInstanceToDrawingElement(copy_reference(other)))
71 {}
72 
73 
74 ComponentInstance::ComponentInstance(const ComponentInstance& other, SUComponentInstanceRef instance_ref):
75  DrawingElement(other, SUComponentInstanceToDrawingElement(instance_ref))
76 {}
77 
78 
80  if (!m_attached && SUIsValid(m_entity)) {
81  SUComponentInstanceRef instance = SUComponentInstanceFromEntity(m_entity);
82  SUResult res = SUComponentInstanceRelease(&instance);
83  assert(res == SU_ERROR_NONE); _unused(res);
84  }
85 }
86 
87 /******************
88 * Public Methods **
89 *******************/
90 /** Copy assignment operator */
92  if (!m_attached && SUIsValid(m_entity)) {
93  SUComponentInstanceRef instance;
94  // Workaround for bug in Sketchup API which prevents an entity that is a group to be cast directly into ComponentInstance
95  if (SUEntityGetType(m_entity) == SURefType_Group) {
96  SUGroupRef group = SUGroupFromEntity(m_entity);
97  instance = SUGroupToComponentInstance(group);
98  }
99  else {
100  instance = SUComponentInstanceFromEntity(m_entity);
101  }
102  SUResult res = SUComponentInstanceRelease(&instance);
103  assert(res == SU_ERROR_NONE); _unused(res);
104  }
105  m_entity = SUComponentInstanceToEntity(copy_reference(other));
107  return *this;
108 }
109 
110 
111 SUComponentInstanceRef ComponentInstance::ref() const {
112  // TODO: Due to a bug in the C API, SUComponentInstanceFromEntity returns null if the reference object is a Group. The workaround is cast to group then to a ComponentInstance.
113  SURefType type = this->entity_type();
114  if (type == SURefType_Group) {
115  SUGroupRef group_ref = SUGroupFromEntity(m_entity);
116  return SUGroupToComponentInstance(group_ref);
117  }
118  return SUComponentInstanceFromEntity(m_entity);
119 }
120 
121 
122 ComponentInstance::operator SUComponentInstanceRef() const {
123  return this->ref();
124 }
125 
126 
128  if (!(*this)) {
129  throw std::logic_error("CW::ComponentInstance::transformation(): ComponentInstance is null");
130  }
131  SUTransformation transform;
132  SUResult res = SUComponentInstanceGetTransform(this->ref(), &transform);
133  assert(res == SU_ERROR_NONE); _unused(res);
134  return Transformation(transform);
135 }
136 
137 
139  if (!(*this)) {
140  throw std::logic_error("CW::ComponentInstance::transformation(): ComponentInstance is null");
141  }
142  SUTransformation su_transform = transform.ref();
143  SUResult res = SUComponentInstanceSetTransform(this->ref(), &su_transform);
144  assert(res == SU_ERROR_NONE); _unused(res);
145 }
146 
147 
149  if (!(*this)) {
150  throw std::logic_error("CW::ComponentInstance::definition(): ComponentInstance is null");
151  }
152  SUComponentDefinitionRef component = SU_INVALID;
153  SUResult res = SUComponentInstanceGetDefinition(this->ref(), &component);
154  assert(res == SU_ERROR_NONE); _unused(res);
155  return ComponentDefinition(component);
156 }
157 
158 
160  if (!(*this)) {
161  throw std::logic_error("CW::ComponentInstance::name(): ComponentInstance is null");
162  }
163  String string;
164  SUStringRef * const string_ref = string;
165  SUResult res = SUComponentInstanceGetName(this->ref(), string_ref);
166  assert(res == SU_ERROR_NONE); _unused(res);
167  return string;
168 }
169 
170 
171 void ComponentInstance::name(const String& string) {
172  if (!(*this)) {
173  throw std::logic_error("CW::ComponentInstance::name(): ComponentInstance is null");
174  }
175  std::string name_string = string.std_string();
176  SUResult res = SUComponentInstanceSetName(this->ref(), name_string.c_str());
177  assert(res == SU_ERROR_NONE); _unused(res);
178 }
179 
180 
181 } /* namespace CW */
bool m_attached
Indicates whether the Entity has been attached to a model.
Definition: Entity.hpp:64
ComponentInstance create_instance() const
bool attached() const
Returns true if the entity is attached to another object.
Definition: Entity.cpp:100
SUComponentInstanceRef copy_reference(const ComponentInstance &other)
Transformation transformation() const
enum SURefType entity_type() const
Returns the type of the entity. See enum SURefType.
Definition: Entity.cpp:234
DrawingElement & operator=(const DrawingElement &other)
SUEntityRef m_entity
The C SUEntityRef that this class wraps.
Definition: Entity.hpp:59
ComponentDefinition definition() const
ComponentInstance & operator=(const ComponentInstance &other)
Definition: Color.hpp:34
SUComponentInstanceRef ref() const