SUAPI-CppWrapper
C++WrapperforSketchUpCAPI
GeometryInput.hpp
1 //
2 // GeometryInput.hpp
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 #ifndef GeometryInput_hpp
29 #define GeometryInput_hpp
30 
31 #include <stdio.h>
32 #include <algorithm>
33 #include <vector>
34 #include <array>
35 #include <unordered_map>
36 
37 #include <SketchUpAPI/geometry.h>
38 #include <SketchUpAPI/model/entities.h>
39 
40 #include "SUAPI-CppWrapper/Geometry.hpp"
41 
42 namespace CW {
43 
44 // Forward declarations:
45 class Model;
46 class Entities;
47 class Face;
48 class Edge;
49 class Material;
50 class MaterialInput;
51 class Layer;
52 class LoopInput;
53 class Loop;
54 
55 /**
56 * Geometry Input class is an abstraction of Sketchup C API's SUGeometryInputRef object. It allows a much easier way for programmers to build Sketchup geometry within this class, before exporting it into a built SUGeometryInputRef object.
57 * See below for an example of GeometryInput operates:
58 GeometryInput geom_input;
59 Entities entities; // This is the entities object that we wish to add the geometry to.
60 std::vector<SUPoint3D> outer_loop{SUPoint3D(0.0,0.0,0.0), SUPoint3D(1.0,0.0,0.0), SUPoint3D(0.0,1.0,0.0)};
61 std::vector<std::vector<SUPoint3D>> inner_loops{{SUPoint3D(0.1,0.1,0.0), SUPoint3D(0.1,0.2,0.0), SUPoint3D(0.2,0.3,0.0)}};
62 GIFace* face = geom_input.add_face(outer_loop, inner_loops); // GeometryInput handles the interface with Sketchup C API when creating geometry.
63 SUResult result = entities.fill(geom_input); // the geometry must be output into a SUEntitiesRef object.
64 
65 */
67  friend class Entities;
68 
69 private:
70  SUGeometryInputRef m_geometry_input;
71 
72  bool m_attached;
73  // GeometryInput objects require that the target model (for inputting information) be known, to ensure that materials and layers assigned to geometry exists in the target model.
74  SUModelRef m_target_model;
75 
76  size_t m_vertex_index = 0;
77 
78  // Tracks the number of GeometrryInput objects have been allocated, to allow the destructor to release an object only at the right time.
79  static std::unordered_map<SUGeometryInputRef, size_t> num_objects_;
80 
81  /**
82  * Creates and returns new SUGeometryInputRef object, used for initializing m_geometry_input. The SUGeometryInputRef object must be released with SUGeometryInputRelease() before this class is destroyed.
83  */
84  static SUGeometryInputRef create_geometry_input();
85 
86 public:
87  /**
88  * Creates a valid, but empty GeometryInput object.
89  * @param target_model - model which will receive this GeometryInput object.
90  */
91  GeometryInput(SUModelRef target_model);
92 
93  /** Copy Constructor **/
94  GeometryInput(const GeometryInput& other);
95 
96  /** Destructor */
98 
99  /**
100  * Copy assignment operator.
101  */
102  GeometryInput& operator=(const GeometryInput& other);
103 
104  /**
105  * Returns Raw SUGeometryInputRef that is stored.
106  */
107  SUGeometryInputRef ref() const;
108 
109  /**
110  * Returns true if the objet is valid, false otherwise.
111  */
112  bool operator!() const;
113 
114  /**
115  * Returns the number of faces have been input into this GeometryInput object.
116  */
117  size_t num_faces() const;
118 
119  /**
120  * Adds a face to the Geometry Input object.
121  * @param face - the face object to be copied into the GeometryInput object. Note that materials and layers will NOT be copied. This must be done manually using face_front_material(), face_back_material(), and face_layer() methods.
122  * @param copy_material_layer - (optional) when true, materials and layers will be copied to the GeometryInput object. Set to false if you are copying faces from another model - you will have to add a material manually.
123  * @return index to the added face.
124  */
125  size_t add_face(const Face &face, bool copy_material_layer = true);
126 
127  /**
128  * Adds a face to the Geometry Input object using the safer LoopInput method, which can deal with inner loops.
129  * @param loops - vector of loops. The first loop in the vector is the outer loop, and all subsequent loops are the inner loops.
130  * @return index to the added face.
131  */
132  size_t add_face(const std::vector<Loop>& loops);
133 
134  size_t add_faces(const std::vector<Face>& faces, bool copy_material_layer = true);
135 
136  /**
137  * Adds an Edge to the Geometry Input object.
138  * @return index to the added edge.
139  */
140  size_t add_edge(const Edge &edge);
141  size_t add_edges(const std::vector<Edge>& edges);
142 
143  /**
144  * Returns true if no geometry has been added to this object.
145  */
146  bool empty() const;
147 
148  /**
149  * Adds a vertex to the GeometryInput object.
150  * @param point - the Point3D location of the vertex to add.
151  * @return the index number of the added vertex
152  */
153  size_t add_vertex(const Point3D& point);
154 
155  /**
156  * Sets all vertices of a geometry input object. Any existing vertices will be overridden.
157  * @param points - vector of points to set as the vertices
158  */
159  void set_vertices(const std::vector<SUPoint3D>& points);
160  void set_vertices(const std::vector<Point3D>& points);
161 
162  /**
163  * Adds an edge to a geometry input object. This method is intended for specifying edges which are not associated with loop inputs. For specifying edge properties on a face use the SULoopInput interface. More...
164  * @param vertex0_index - vertex index of start point of edge.
165  * @param vertex1_index - vertex index of end point of edge.
166  * @return index of added edge
167  */
168  size_t add_edge(size_t vertex0_index, size_t vertex1_index);
169 
170  /**
171  * Sets the hidden flag of an edge in a geometry input object which is not associated with a loop input.
172  * @param edge_index - index of the edge to set the hidden flag.
173  * @param hidden - the flag to set.
174  */
175  void edge_hidden(size_t edge_index, bool hidden);
176 
177  /**
178  * Sets the soft flag of an edge in a geometry input object which is not associated with a loop input.
179  * @since SketchUp 2017, API 5.0
180  * @param edge_index - The zero-based index of the edge which is not associated with a loop input.
181  * @param soft - The flag to set.
182  */
183  void edge_soft(size_t edge_index, bool soft);
184 
185  /**
186  *Sets the smooth flag of an edge in a geometry input object which is not associated with a loop input.
187  * @since SketchUp 2017, API 5.0
188  * @param edge_index - The zero-based index of the edge which is not associated with a loop input.
189  * @param smooth - The flag to set.
190  */
191  void edge_smooth(size_t edge_index, bool smooth);
192 
193  /**
194  * Sets the material of an edge in the geometry input.
195  * @since SketchUp 2017, API 5.0
196  * @param edge_index - Index of the edge to set the material.
197  * @param material - The material to be set.
198  */
199  void edge_material(size_t edge_index, const Material& material);
200 
201  /**
202  * Sets the layer of an edge in the geometry input.
203  * @since SketchUp 2017, API 5.0
204  * @param edge_index - Index of the edge to set the layer.
205  * @param layer - The layer to be set.
206  */
207  void edge_layer(size_t edge_index, const Layer& layer);
208 
209  /**
210  * Adds a curve to a geometry input object. This method is intended for specifying curves which are not associated with loop inputs. For specifying curves on faces use the SULoopInput interface.
211  * @since SketchUp 2017, API 5.0
212  * @param num_edges - The number of edges to be used in the curve.
213  * @param edge_indices - The edge indices to be used in defining the curve.
214  * @param added_curve_index (optional) If not NULL, returns the index of the added curve.
215  */
216  size_t add_curve(const std::vector<size_t>& edge_indices);
217 
218  /**
219  * Adds an arccurve to a geometry input object. In addition to adding an arccurve to the geometry input this method will append num_segments edges to the geometry's edge collection where control_edge_index is the index of the first new edge. Also, num_segments-1 vertices along the arc will be appended to the geometry's collection of verttices. In order to include an arccurve in a loop the user only needs add the arccurve's points to a loop using SULoopInputAddVertexIndex.
220  * @since SketchUp 2017 M2, API 5.2
221  * @param start_point - The index of the vertex at the start of the arc.
222  * @param end_point - The index of the vertex at the end of the arc.
223  * @param center - The center point of the arc's circle.
224  * @param normal - The normal vector of the arc plane.
225  * @param num_segments - The number of edges for the arc.
226  * @return pair of size_t values:
227  - first - added_curve_index - the index of the added curve.
228  * - second - control_edge_index - the index of the the arc's control edge which can be used to set the arc's edge properties.
229  */
230  std::pair<size_t, size_t> add_arc_curve(size_t start_point, size_t end_point, const Point3D& center, const Vector3D& normal, size_t num_segments);
231 
232  /**
233  * Adds a face to a geometry input object with a given outer loop for the face.
234  * @param outer_loop - The outer loop to be set for the face. If the function succeeds (i.e. returns SU_ERROR_NONE), this loop will be deallocated.
235  * @return returns the index of the added face.
236  */
237  size_t add_face(LoopInput& loop_input);
238 
239  /**
240  * Sets a flag in the geometry input that, when true, will create a face by reversing the orientations of all of its loops.
241  * @param face_index - Index of the face to be reversed.
242  * @param reverse - The given reverse flag.
243  */
244  void face_reverse(size_t face_index, bool reverse);
245 
246  /**
247  * Sets the layer of a face in the geometry input.
248  * @param face_index - Index of the face to be reversed.
249  * @param layer - The layer to be set.
250  */
251  void face_layer(size_t face_index, const Layer& layer);
252 
253  /**
254  * Adds an inner loop to a face in the geometry input.
255  * @param face_index - Index of the face to receive the inner loop.
256  * @param loop_input - The inner loop to be added. If the function succeeds (i.e. returns SU_ERROR_NONE), this loop will be deallocated.
257  */
258  void face_add_inner_loop(size_t face_index, LoopInput& inner_loop);
259 
260  /**
261  * Sets the front material of a face in the geometry input.
262  * @param face_index - Index of the face to receive the material.
263  * @param material_input - The material input to set.
264  */
265  void face_front_material(size_t face_index, MaterialInput& material_input);
266 
267  /**
268  * Sets the back material of a face in the geometry input.
269  * @param face_index - Index of the face to receive the material.
270  * @param material_input - The material input to set.
271  */
272  void face_back_material(size_t face_index, MaterialInput& material_input);
273 
274  /**
275  * Sets a flag in the geometry input that, when true, will create a hidden face.
276  * @since SketchUp 2017, API 5.0
277  * @param face_index - Index of the face to be hidden.
278  * @param hidden - The given hidden flag.
279  */
280  void face_hidden(size_t face_index, bool hidden);
281 
282  /**
283  * Returns all the various geometry counts.
284  * @since SketchUp 2018, API 6.0
285  * @return array of counts:
286  * - [0] - vertices_count - The total count of vertices.
287  * - [1] - faces_count The total count of faces.
288  * - [2] - edge_count The total count of edges.
289  * - [3] - curve_count The total count of curves.
290  * - [4] - arc_count The total count of arcs.
291  */
292  std::array<size_t, 5> counts() const;
293 
294  /**
295  * Hash function for use with unordered_map
296  */
298 
299 };
300 
301 
302 } /* namespace CW */
303 
304 namespace std {
305  template <> struct hash<SUGeometryInputRef>
306  {
307  size_t operator()(const SUGeometryInputRef& k) const
308  {
309  static const size_t shift = (size_t)log2(1 + sizeof(SUGeometryInputRef));
310  return (size_t)(k.ptr) >> shift;
311  }
312  };
313 }
314 
315 
316 #endif /* GeometryInput_hpp */
size_t add_vertex(const Point3D &point)
void set_vertices(const std::vector< SUPoint3D > &points)
std::array< size_t, 5 > counts() const
void edge_soft(size_t edge_index, bool soft)
size_t add_curve(const std::vector< size_t > &edge_indices)
void face_front_material(size_t face_index, MaterialInput &material_input)
STL namespace.
void face_reverse(size_t face_index, bool reverse)
GeometryInput(SUModelRef target_model)
size_t add_face(const Face &face, bool copy_material_layer=true)
void face_hidden(size_t face_index, bool hidden)
void face_add_inner_loop(size_t face_index, LoopInput &inner_loop)
void edge_material(size_t edge_index, const Material &material)
bool operator!() const
GeometryInput & operator=(const GeometryInput &other)
void face_back_material(size_t face_index, MaterialInput &material_input)
bool empty() const
size_t add_edge(const Edge &edge)
void edge_hidden(size_t edge_index, bool hidden)
SUGeometryInputRef ref() const
Definition: Color.hpp:34
std::pair< size_t, size_t > add_arc_curve(size_t start_point, size_t end_point, const Point3D &center, const Vector3D &normal, size_t num_segments)
size_t num_faces() const
void edge_layer(size_t edge_index, const Layer &layer)
void edge_smooth(size_t edge_index, bool smooth)
void face_layer(size_t face_index, const Layer &layer)