29 #define _unused(x) ((void)(x)) 34 #include "SUAPI-CppWrapper/Transformation.hpp" 36 #include <SketchUpAPI/geometry/vector3d.h> 37 #include <SketchUpAPI/geometry/point3d.h> 38 #include <SketchUpAPI/geometry/plane3d.h> 40 #include "SUAPI-CppWrapper/model/Axes.hpp" 41 #include "SUAPI-CppWrapper/model/Face.hpp" 42 #include "SUAPI-CppWrapper/model/Loop.hpp" 43 #include "SUAPI-CppWrapper/model/LoopInput.hpp" 44 #include "SUAPI-CppWrapper/model/Vertex.hpp" 45 #include "SUAPI-CppWrapper/model/Material.hpp" 55 m_transformation(transformation)
63 m_transformation(SU_INVALID)
65 SUResult res = SUTransformationSetFromPointAndAxes(&m_transformation, origin, x_axis, y_axis, z_axis);
66 assert(res == SU_ERROR_NONE); _unused(res);
74 m_transformation(SU_INVALID)
76 SUResult res = SUTransformationScale(&m_transformation, scalar);
77 assert(res == SU_ERROR_NONE); _unused(res);
82 m_transformation(SU_INVALID)
84 SUResult res = SUTransformationNonUniformScale(&m_transformation, x_scale, y_scale, z_scale);
85 assert(res == SU_ERROR_NONE); _unused(res);
90 m_transformation(SU_INVALID)
92 SUResult res = SUTransformationTranslation(&m_transformation, translation);
93 assert(res == SU_ERROR_NONE); _unused(res);
98 m_transformation(SU_INVALID)
100 SUResult res = SUTransformationScaleAboutPoint(&m_transformation, translation, scalar);
101 assert(res == SU_ERROR_NONE); _unused(res);
106 m_transformation(SU_INVALID)
108 SUResult res = SUTransformationSetFromPointAndNormal(&m_transformation, translation, normal);
109 assert(res == SU_ERROR_NONE); _unused(res);
114 m_transformation(SU_INVALID)
116 SUResult res = SUTransformationRotation(&m_transformation, point, vector, angle);
117 assert(res == SU_ERROR_NONE); _unused(res);
122 m_transformation(SU_INVALID)
124 SUResult res = SUTransformationInterpolate(&m_transformation, transform1, transform2, weight);
125 assert(res == SU_ERROR_NONE); _unused(res);
129 double Transformation::determinant()
const {
133 m_transformation.values[12] * m_transformation.values[9] * m_transformation.values[6] * m_transformation.values[3]-m_transformation.values[8] * m_transformation.values[13] * m_transformation.values[6] * m_transformation.values[3]-m_transformation.values[12] * m_transformation.values[5] * m_transformation.values[10] * m_transformation.values[3]+m_transformation.values[4] * m_transformation.values[13] * m_transformation.values[10] * m_transformation.values[3]+
134 m_transformation.values[8] * m_transformation.values[5] * m_transformation.values[14] * m_transformation.values[3]-m_transformation.values[4] * m_transformation.values[9] * m_transformation.values[14] * m_transformation.values[3]-m_transformation.values[12] * m_transformation.values[9] * m_transformation.values[2] * m_transformation.values[7]+m_transformation.values[8] * m_transformation.values[13] * m_transformation.values[2] * m_transformation.values[7]+
135 m_transformation.values[12] * m_transformation.values[1] * m_transformation.values[10] * m_transformation.values[7]-m_transformation.values[0] * m_transformation.values[13] * m_transformation.values[10] * m_transformation.values[7]-m_transformation.values[8] * m_transformation.values[1] * m_transformation.values[14] * m_transformation.values[7]+m_transformation.values[0] * m_transformation.values[9] * m_transformation.values[14] * m_transformation.values[7]+
136 m_transformation.values[12] * m_transformation.values[5] * m_transformation.values[2] * m_transformation.values[11]-m_transformation.values[4] * m_transformation.values[13] * m_transformation.values[2] * m_transformation.values[11]-m_transformation.values[12] * m_transformation.values[1] * m_transformation.values[6] * m_transformation.values[11]+m_transformation.values[0] * m_transformation.values[13] * m_transformation.values[6] * m_transformation.values[11]+
137 m_transformation.values[4] * m_transformation.values[1] * m_transformation.values[14] * m_transformation.values[11]-m_transformation.values[0] * m_transformation.values[5] * m_transformation.values[14] * m_transformation.values[11]-m_transformation.values[8] * m_transformation.values[5] * m_transformation.values[2] * m_transformation.values[15]+m_transformation.values[4] * m_transformation.values[9] * m_transformation.values[2] * m_transformation.values[15]+
138 m_transformation.values[8] * m_transformation.values[1] * m_transformation.values[6] * m_transformation.values[15]-m_transformation.values[0] * m_transformation.values[9] * m_transformation.values[6] * m_transformation.values[15]-m_transformation.values[4] * m_transformation.values[1] * m_transformation.values[10] * m_transformation.values[15]+m_transformation.values[0] * m_transformation.values[5] * m_transformation.values[10] * m_transformation.values[15];
143 std::array<double, 4> Transformation::multiply4x1(std::array<double, 4> matrix4_1)
const {
144 std::array<double, 4> output;
145 for (
size_t i=0; i < 4; ++i) {
152 output[i] = (m_transformation.values[i] * matrix4_1[0]) +
153 (m_transformation.values[i+4] * matrix4_1[1]) +
154 (m_transformation.values[i+8] * matrix4_1[2]) +
155 (m_transformation.values[i+12] * matrix4_1[3]);
163 double Transformation::operator[](
size_t i)
const {
165 throw std::out_of_range(
"CW::Transformation::operator[](): index range is between 0 and 15");
167 return m_transformation.values[i];
170 double& Transformation::operator[](
size_t i) {
172 throw std::out_of_range(
"CW::Transformation::operator[](): index range is between 0 and 15");
174 return m_transformation.values[i];
178 SUTransformation Transformation::ref()
const {
179 return m_transformation;
182 Transformation::operator SUTransformation()
const {
186 Transformation::operator
const SUTransformation*()
const {
187 return &m_transformation;
193 SUResult res = SUTransformationIsIdentity(&m_transformation, &is_identity);
194 assert(res == SU_ERROR_NONE); _unused(res);
200 SUTransformation
inverse = SU_INVALID;
201 SUResult res = SUTransformationGetInverse(&m_transformation, &inverse);
202 assert(res == SU_ERROR_NONE); _unused(res);
208 SUVector3D
x_axis = SU_INVALID;
209 SUResult res = SUTransformationGetXAxis(&m_transformation, &x_axis);
210 assert(res == SU_ERROR_NONE); _unused(res);
216 SUVector3D
y_axis = SU_INVALID;
217 SUResult res = SUTransformationGetYAxis(&m_transformation, &y_axis);
218 assert(res == SU_ERROR_NONE); _unused(res);
224 SUVector3D
z_axis = SU_INVALID;
225 SUResult res = SUTransformationGetZAxis(&m_transformation, &z_axis);
226 assert(res == SU_ERROR_NONE); _unused(res);
233 SUResult res = SUTransformationGetZRotation(&m_transformation, &z_rotation);
234 assert(res == SU_ERROR_NONE); _unused(res);
240 if (m_transformation.values[15] == 1.0) {
244 assert(m_transformation.values[15] != 0.0);
245 for (
size_t i=0; i < 15; ++i) {
246 m_transformation.values[i] = m_transformation.values[i] / m_transformation.values[15];
248 m_transformation.values[15] = 1.0;
254 SUPoint3D
origin = SU_INVALID;
255 SUResult res = SUTransformationGetOrigin(&m_transformation, &origin);
256 assert(res == SU_ERROR_NONE); _unused(res);
262 if (m_transformation.values[15] == 1.0) {
263 return Vector3D( m_transformation.values[12], m_transformation.values[13], m_transformation.values[14]);
265 return Vector3D( m_transformation.values[12] / m_transformation.values[15], m_transformation.values[13] / m_transformation.values[15], m_transformation.values[14] / m_transformation.values[15]);
270 SUTransformation out_transform = SU_INVALID;
271 SUResult res = SUTransformationMultiply(&m_transformation, &transform.m_transformation, &out_transform);
272 assert(res == SU_ERROR_NONE); _unused(res);
282 throw std::invalid_argument(
"CW::Transformation::operator*(const Vector3D &lhs, const Transformation &rhs): Vector3D given is null");
284 SUVector3D transformed = rhs;
285 SUResult res = SUVector3DTransform(&lhs.m_transformation, &transformed);
286 assert(res == SU_ERROR_NONE); _unused(res);
300 throw std::invalid_argument(
"CW::Transformation::operator*(const Point3D &lhs, const Transformation &rhs): Point3D given is null");
302 SUPoint3D transformed = rhs;
303 SUResult res = SUPoint3DTransform(&lhs.m_transformation, &transformed);
304 assert(res == SU_ERROR_NONE); _unused(res);
320 throw std::invalid_argument(
"CW::Transformation::operator*(const Transformation &lhs, const Plane3D &rhs): Plane3D given is null");
322 SUPlane3D transformed = rhs;
323 SUResult res = SUPlane3DTransform(&lhs.m_transformation, &transformed);
324 assert(res == SU_ERROR_NONE); _unused(res);
338 throw std::invalid_argument(
"CW::Transformation::operator*(const Face &lhs, const Transformation &rhs): Face given is null");
341 std::vector<Vertex> outer_vertices = lhs.outer_loop().
vertices();
342 std::vector<Point3D> trans_outer_points;
343 trans_outer_points.reserve(outer_vertices.size());
344 for (
size_t i=0; i < outer_vertices.size(); ++i) {
345 trans_outer_points.push_back(outer_vertices[i].position() * rhs);
347 LoopInput outer_loop_input = lhs.outer_loop().loop_input();
348 Face trans_face(trans_outer_points, outer_loop_input);
351 for (
size_t j=0; j < inner_loops.size(); ++j) {
352 std::vector<Vertex> inner_vertices = inner_loops[j].vertices();
353 std::vector<Point3D> trans_inner_points;
354 trans_inner_points.reserve(inner_vertices.size());
355 for (
size_t i=0; i < inner_vertices.size(); ++i) {
356 trans_inner_points.push_back(inner_vertices[i].position() * rhs);
358 LoopInput inner_loop_input = inner_loops[j].loop_input();
361 if (!!lhs.material()) {
362 trans_face.material(lhs.material());
370 for (
size_t i=0; i < 16; ++i) {
372 if (i == 3 || i == 7 || i == 11) {
375 if (!(fabs((*
this)[i] - transform[i]) < epsilon)) {
383 bool Transformation::operator==(
const Transformation transform)
const {
384 return this->
equal(transform);
393 throw std::invalid_argument(
"CW::Transformation::transformation_rotate_about_line(): Line3D given is null");
398 SUTransformation transform;
399 double u = line.direction.x;
400 double v = line.direction.y;
401 double w = line.direction.z;
402 double a = line.point.x;
403 double b = line.point.y;
404 double c = line.point.z;
405 double cos_angle = cos(angle);
406 double sin_angle = sin(angle);
407 double u2 = pow(u,2);
408 double v2 = pow(v,2);
409 double w2 = pow(w,2);
420 transform.values[0] = u2 + (cos_angle * (v2 + w2));
421 transform.values[1] = (u * v * (1 - cos_angle)) + (w * sin_angle);
422 transform.values[2] = (u * w * (1 - cos_angle)) - (v * sin_angle);
423 transform.values[3] = 0;
425 transform.values[4] = (u * v * (1 - cos_angle)) - (w * sin_angle);
426 transform.values[5] = v2 + ((u2 + w2) * cos_angle);
427 transform.values[6] = (v * w * (1 - cos_angle)) + (u * sin_angle);
428 transform.values[7] = 0;
430 transform.values[8] = (u * w * (1 - cos_angle)) + (v * sin_angle);
431 transform.values[9] = (v * w * (1 - cos_angle)) - (u * sin_angle);
432 transform.values[10] = w2 + ((u2 + v2) * cos_angle);
433 transform.values[11] = 0;
435 transform.values[12] = (( (a * (v2 + w2)) - (u * (bv + cw)) ) * (1 - cos_angle)) + ((bw - cv) * sin_angle);
436 transform.values[13] = (( (b * (u2 + w2)) - (v * (au + cw)) ) * (1 - cos_angle)) + ((cu - aw) * sin_angle);
437 transform.values[14] = (( (c * (u2 + v2)) - (w * (au + bv)) ) * (1 - cos_angle)) + ((av - bu) * sin_angle);
438 transform.values[15] = 1;
void add_inner_loop(std::vector< Point3D > &points, LoopInput &loop_input)
std::vector< Loop > inner_loops() const
bool copy_attributes_from(const Entity &entity)
Copies attributes from another Entity object to this one.
std::vector< Vertex > vertices() const