HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GQ_StraightSkeleton.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: Straight skeleton construction tool
7  *
8  */
9 
10 #ifndef __GQ_StraightSkeleton_h__
11 #define __GQ_StraightSkeleton_h__
12 
13 #include "GQ_API.h"
14 #include <GA/GA_Edge.h>
15 #include <UT/UT_Matrix4.h>
16 #include <UT/UT_Pair.h>
17 #include <UT/UT_Array.h>
18 #include <UT/UT_String.h>
19 #include <UT/UT_StringHolder.h>
20 #include <UT/UT_Vector3.h>
21 #include <UT/UT_Error.h>
22 
23 class GU_Detail;
24 class GQ_Detail;
25 class GQ_Point;
26 class GQ_Edge;
27 class GQ_Face;
28 class GA_PrimitiveGroup;
29 class GA_PointGroup;
30 class UT_ErrorManager;
31 
32 /// These internal helper classes are named generically enough that they could
33 /// potentially conflict with classes in other files. We don't want to expose
34 /// their implementation, and we can't forward declare embedded helper classes,
35 /// so we resort to wrapping them in a name space as the next best thing.
36 namespace GQ_StraightSkeletonImpl {
37 }
38 
39 /// Straight skeleton computation for general polygonal figures in a 2D
40 /// plane.
41 ///
42 /// The algorithm used is a kinetic triangulation, originally described by
43 /// Aichholzer, Aurenhammer in "Straight Skeletons for General Polygonal
44 /// Figures in the Plane", with some implementation details filled in by
45 /// Palfrader, Held and Huber in "On Computing Straight Skeletons by Means
46 /// of Kinetic Triangulations".
47 ///
48 /// We use GQ_PolyDelaunay internally for the initial triangulation.
49 
51 {
52 public:
53  /// Some local typedefs for our helper classes to avoid having to fully
54  /// qualify the names everywhere.
55 
56  explicit GQ_StraightSkeleton();
57  virtual ~GQ_StraightSkeleton();
58 
59  /// Set the plane where triangulation happens.
60  void setPlane(const UT_Vector3 &normal, fpreal distance);
61  /// Fit a plane to the input points. Returns true if it succeeded.
62  bool fitPlane(const GU_Detail *gdp,
63  const GA_PointGroup *pointGroup = 0,
64  UT_Vector3 *outNormal = 0,
65  fpreal *outDistance = 0);
66 
67  /// How to determine inside/outside from the input graph.
68  enum InOutType
69  {
70  /// The vertex order of any primitives referencing an edge determines
71  /// which side of the edge is considered the inside or the outside.
72  ///
73  /// NB: This is the fallback method if any of the other ones fail.
74  VERTEX_ORDER = 0,
75 
76  /// Outermost edge loops, if any, separate the outside region from the
77  /// inside(s).
79 
80  /// A nested separation of the plane into outside and inside regions.
82 
83  /// A nested separation of the plane into outside and inside regions
84  /// with inside regions extending through shared edges.
85  ALTERNATING_REACHABILITY_WITH_SHARED_EDGES
86  };
87 
88  void setInOutType(InOutType type) { myInOutType = type; }
89  InOutType getInOutType() const { return myInOutType; }
90 
91  /// Assigning attributes to use for edge weights turns this into a
92  /// weighted straight skeleton. We only support positive weighted
93  /// straight skeletons, ignoring any zero or negative edge weights
94  /// and replacing them with a weight of 1.
95  ///
96  /// Edge weights can be queried from a vertex, point, or primitive
97  /// attribute, in that order of priority.
98  void setInsideWeightAttrib(const char *attrib)
99  { myInsideWeightAttrib = attrib; }
101  { return myInsideWeightAttrib; }
102  void setOutsideWeightAttrib(const char *attrib)
103  { myOutsideWeightAttrib = attrib; }
105  { return myOutsideWeightAttrib; }
106 
107  /// The tolerance used to identify coincident points during triangle
108  /// collapses.
109  void setDistanceTol(fpreal64 tol);
110  fpreal64 getDistanceTol() const { return myDistanceTol; }
111 
112  /// The tolerance used to identify parallel edges to detect infinitely
113  /// fast moving wavefront points during triangle collapsed. Bisectors
114  /// of edges with angles (in radians) less than this will be considered
115  /// infinitely fast.
116  void setParallelismTol(fpreal64 tol);
117  fpreal64 getParallelismTol() const { return myParallelTol; }
118 
119  void computeSkeleton(GU_Detail *gdp,
120  const GA_PrimitiveGroup *prim_group);
121  UT_ErrorSeverity getSkeletonComputationErrorSeverity();
122  void getSkeletonComputationErrors(UT_ErrorManager &errors);
123 
125  {
126  OFFSET_CURVES = 0,
127  OFFSET_SURFACES = 1
128  };
129 
130  /// The distance parameter is actually interpreted as the time during the
131  /// wavefront propagation. This is the same thing for skeletons computed
132  /// without local edge weights and, for skeletons with local edge weights,
133  /// where our interest really lies.
134  void buildOffsetGeometry(GU_Detail *gdp, OffsetGeoType type,
135  fpreal64 distance, int ndivs,
136  bool inside, bool outside,
137  bool keep_input,
138  const GA_PrimitiveGroup *input_group,
139  GA_PrimitiveGroup *inside_group,
140  GA_PrimitiveGroup *outside_group,
141  bool split_curves_to_omit_end_caps,
142  const char *edge_dist_attrib_name,
143  const char *edge_speed_attrib_name,
144  bool updatePointNormals = true);
145 
146  /// Project 3D point onto plane.
147  UT_Vector2 make2D(const UT_Vector3 &pos) const;
148  UT_Vector3 make3D(const UT_Vector2 &pos) const;
149 
150 private:
151  class Skeleton;
152 
153  /// Set up my*Transform member variables from the plane
154  /// normal/distance.
155  void calcTransforms(const UT_Vector3 &normal, fpreal distance);
156 
157  /// Transform from 3D space to plane
158  UT_Matrix4 my3to2Transform;
159  /// Transform from plane to 3D space
160  UT_Matrix4 my2to3Transform;
161  UT_Vector3 myPlaneNormal;
162  fpreal myPlaneDistance;
163 
164  InOutType myInOutType;
165  fpreal64 myDistanceTol;
166  fpreal64 myParallelTol;
167 
168  UT_StringHolder myInsideWeightAttrib;
169  UT_StringHolder myOutsideWeightAttrib;
170 
171  Skeleton *mySkel;
172 };
173 
174 #endif
void setOutsideWeightAttrib(const char *attrib)
#define GQ_API
Definition: GQ_API.h:10
InOutType
How to determine inside/outside from the input graph.
UT_ErrorSeverity
Definition: UT_Error.h:25
const UT_StringHolder & getOutsideWeightAttrib() const
void setInOutType(InOutType type)
void setInsideWeightAttrib(const char *attrib)
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:698
double fpreal64
Definition: SYS_Types.h:192
const UT_StringHolder & getInsideWeightAttrib() const
double fpreal
Definition: SYS_Types.h:270
fpreal64 getDistanceTol() const
A nested separation of the plane into outside and inside regions.
A global error manager scope.
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
InOutType getInOutType() const
fpreal64 getParallelismTol() const