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