All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vertex.h
Go to the documentation of this file.
1 //
2 // Copyright 2013 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef HBRVERTEX_H
26 #define HBRVERTEX_H
27 
28 #include <assert.h>
29 #include <iostream>
30 #include <iterator>
31 #include <vector>
32 #include "../hbr/fvarData.h"
33 #include "../hbr/face.h"
34 
35 #include "../version.h"
36 
37 namespace OpenSubdiv {
38 namespace OPENSUBDIV_VERSION {
39 
40 template <class T> class HbrHalfedge;
41 template <class T> class HbrHalfedgeCompare;
42 template <class T> class HbrVertex;
43 template <class T> class HbrVertexOperator;
44 template <class T> class HbrFaceOperator;
45 template <class T> class HbrHalfedgeOperator;
46 
47 template <class T> class HbrVertex {
48 
49 public:
50  HbrVertex();
51  HbrVertex(int vid, const T &data, int fvarwidth) {
52  Initialize(vid, data, fvarwidth);
53  }
54  void Initialize(int vid, const T &data, int fvarwidth);
55  ~HbrVertex();
56  void Destroy(HbrMesh<T> *mesh = 0);
57 
58  // Registers an incident edge with the vertex
60 
61  // Unregister an incident edge with the vertex
63 
64  // Checks if removal of the indicated incident edge will result
65  // in a singular vertex
67 
68  // Sets up vertex flags after the vertex has been bound to a mesh
69  void Finish();
70 
71  // Compute the valence of this vertex
72  int GetValence() const;
73 
74  // Compute the valence of this vertex including only edges which
75  // are "coarse" (highest level edges)
76  int GetCoarseValence() const;
77 
78  // Return vertex ID
79  int GetID() const { return id; }
80 
81  // Return vertex data
82  T& GetData() { return data; }
83 
84  // Return vertex data
85  const T& GetData() const { return data; }
86 
87  // Returns the facevarying data which is matched to the face.
88  // This may either be the "generic" facevarying item (fvardata, so
89  // data.GetFace() == face) or one specifically registered to the
90  // face (in the middle of morefvardata, so data.GetFace() ==
91  // face). If we require storage for a facevarying data designed to
92  // store discontinuous values for this face, we must have called
93  // NewFVarData before GetFVarData will give it to us.
95 
96  // Returns new facevarying data matched to the face
98 
99  // Return any incident face attached to the vertex
100  HbrFace<T>* GetFace() const;
101 
102  // Return the mesh to which this vertex belongs
103  HbrMesh<T>* GetMesh() const;
104 
105  // Return an edge connected to dest
106  HbrHalfedge<T>* GetEdge(const HbrVertex<T>* dest) const;
107 
108  // Return an edge connected to vertex with id dest
109  HbrHalfedge<T>* GetEdge(int dest) const;
110 
111  // Given an edge, returns the next edge in counterclockwise order
112  // around this vertex. Note well: this is only the next halfedge,
113  // which means that all edges returned by this function are
114  // guaranteed to have the same origin vertex (ie this vertex). In
115  // boundary cases if you are interested in all edges you will not
116  // get the last edge with this function. For that reason,
117  // GetSurroundingEdges is preferred.
119 
120  // Given an edge, returns the previous edge (ie going clockwise)
121  // around this vertex
123 
124  // Quadedge-like algebra subset. Since we are dealing with
125  // halfedges and not symmetric edges, these functions accept a
126  // destination vertex which indicates the (possibly imaginary)
127  // halfedge we are considering, and return the destination vertex
128  // of the desired (also possibly imaginary) halfedge. Also,
129  // currently they are potentially very inefficient and should be
130  // avoided.
131  HbrVertex<T>* GetQEONext(const HbrVertex<T>* dest) const;
134  HbrVertex<T>* GetQEOPrev(const HbrVertex<T>* dest) const;
135  HbrVertex<T>* GetQELNext(const HbrVertex<T>* dest) const;
136 
137  // Returns true if the vertex is on a boundary edge
138  bool OnBoundary() const;
139 
140  // Returns true if the vertex has a facevarying mask which is
141  // smooth (0).
142  bool IsFVarSmooth(int datum);
143 
144  // Returns true if all facevarying data has facevarying mask which
145  // is smooth
146  bool IsFVarAllSmooth();
147 
148  // Returns true if the vertex has a facevarying mask which is dart
149  // (1).
150  bool IsFVarDart(int datum);
151 
152  // Returns true if the vertex is a facevarying corner for any
153  // incident face, where "cornerness" is defined as having two
154  // incident edges that make up a face both being facevarying
155  // edges.
156  bool IsFVarCorner(int datum);
157 
158  // Returns the sharpness of the vertex
159  float GetSharpness() const { return sharpness; }
160 
161  // Sets the sharpness of the vertex
162  void SetSharpness(float sharp) { sharpness = sharp; ClearMask(); }
163 
164  // Returns whether the corner is sharp at the current level of
165  // subdivision (next = false) or at the next level of subdivision
166  // (next = true).
167  bool IsSharp(bool next) const { return (next ? (sharpness > 0.0f) : (sharpness >= 1.0f)); }
168 
169  // Sets the vertex mask if the vertex is sharp to reflect that
170  // it's a corner
171  void ClearMask() {
172  mask0 = mask1 = 0; validmask = 0; volatil = 0;
173  }
174 
175  // Returns the integer mask of the vertex at the current level of
176  // subdivision (next = false) or at the next level of subdivision
177  // (next = true)
178  unsigned char GetMask(bool next);
179 
180  // Returns the facevarying integer mask of the vertex
181  unsigned char GetFVarMask(int datum);
182 
183  // Computes the "fractional mask" of the vertex at the current
184  // subdivision level, based on the fractional sharpnesses of any
185  // adjacent sharp edges. The fractional mask is a value between 0
186  // and 1
187  float GetFractionalMask() const;
188 
189  // Returns whether the vertex is singular (has two separate
190  // incident halfedge cycles)
191  bool IsSingular() const { return nIncidentEdges > 1; }
192 
193  // Collect the ring of edges around this vertex. Note well: not
194  // all edges in this list will have an orientation where the
195  // origin of the edge is this vertex! This function requires an
196  // output iterator; to get the edges into a std::vector, use
197  // GetSurroundingEdges(std::back_inserter(myvector))
198  template <typename OutputIterator>
199  void GetSurroundingEdges(OutputIterator edges) const;
200 
201  // Apply an edge operator to each edge in the ring of edges
202  // around this vertex
204 
205  // Collect the ring of vertices around this vertex (the ones that
206  // share an edge with this vertex). This function requires an
207  // output iterator; to get the vertices into a std::vector, use
208  // GetSurroundingVertices(std::back_inserter(myvector))
209  template <typename OutputIterator>
210  void GetSurroundingVertices(OutputIterator vertices) const;
211 
212  // Apply a vertex operator to each vertex in the ring of vertices
213  // around this vertex
215 
216  // Applys an operator to the ring of faces around this vertex
218 
219  // Returns the parent, which can be a edge, face, or vertex
220  HbrHalfedge<T>* GetParentEdge() const { return (parentType == k_ParentEdge ? parent.edge : 0); }
221  HbrFace<T>* GetParentFace() const { return (parentType == k_ParentFace ? parent.face : 0); }
222  HbrVertex<T>* GetParentVertex() const { return (parentType == k_ParentVertex ? parent.vertex : 0); }
223 
224  // Set the parent pointer
225  void SetParent(HbrHalfedge<T>* edge) { assert(!edge || !parent.vertex); parentType = k_ParentEdge; parent.edge = edge; }
226  void SetParent(HbrFace<T>* face) { assert(!face || !parent.vertex); parentType = k_ParentFace; parent.face = face; }
227  void SetParent(HbrVertex<T>* vertex) { assert(!vertex || !parent.vertex); parentType = k_ParentVertex; parent.vertex = vertex; }
228 
229  // Subdivides the vertex and returns the child vertex
231 
232  // Refines the ring of faces around this vertex
233  void Refine();
234 
235  // Make sure the vertex has all faces in the ring around it
236  void GuaranteeNeighbors();
237 
238  // Indicates that the vertex may have a missing face neighbor and
239  // may need to guarantee its neighbors in the future
241  neighborsguaranteed = 0;
242  // Its mask is also invalidated
243  validmask = 0;
244  }
245 
246  // True if the edge has a subdivided child vertex
247  bool HasChild() const { return vchild!=-1; }
248 
249  // Remove the reference to subdivided vertex
250  void RemoveChild() { vchild = -1; }
251 
252  // Returns true if the vertex still has an incident edge (in other
253  // words, it belongs to a face)
254  bool IsReferenced() const { return references != 0; }
255 
256  // Returns true if the vertex is extraordinary
257  bool IsExtraordinary() const { return extraordinary; }
258 
259  // Tag the vertex as being extraordinary
260  void SetExtraordinary() { extraordinary = 1; }
261 
262  // Returns whether the vertex is volatile (incident to a semisharp
263  // edge or semisharp corner)
264  bool IsVolatile() { if (!validmask) GetMask(false); return volatil; }
265 
266  // Simple bookkeeping needed for garbage collection by HbrMesh
267  bool IsCollected() const { return collected; }
268  void SetCollected() { collected = 1; }
269  void ClearCollected() { collected = 0; }
270 
271  // Bookkeeping to see if a vertex edit exists for this vertex
272  bool HasVertexEdit() const { return hasvertexedit; }
273  void SetVertexEdit() { hasvertexedit = 1; }
274  void ClearVertexEdit() { hasvertexedit = 0; }
275 
276  // Returns memory statistics
277  unsigned long GetMemStats() const;
278 
279  // Returns true if the vertex is connected. This means that it has
280  // an incident edge
281  bool IsConnected() const { return nIncidentEdges > 0; }
282 
283  // Return an incident edge to this vertex, which happens to be the
284  // first halfedge of the cycles.
286  if (nIncidentEdges > 1) {
287  return incident.edges[0];
288  } else if (nIncidentEdges == 1) {
289  return incident.edge;
290  } else {
291  return 0;
292  }
293  }
294 
295  // Sharpness and mask constants
296  enum Mask {
297  k_Smooth = 0,
298  k_Dart = 1,
299  k_Crease = 2,
300  k_Corner = 3,
302  };
303 
304  // Increment the usage counter on the vertex
305  void IncrementUsage() { used++; }
306 
307  // Decrement the usage counter on the vertex
308  void DecrementUsage() { used--; }
309 
310  // Check the usage counter on the vertex
311  bool IsUsed() const { return used || (vchild != -1); }
312 
313  // Used by block allocator
314  HbrVertex<T>*& GetNext() { return parent.vertex; }
315 
316  // Returns the blind pointer to client data
317  void *GetClientData(HbrMesh<T>* mesh) const {
318  return mesh->GetVertexClientData(id);
319  }
320 
321  // Sets the blind pointer to client data
322  void SetClientData(HbrMesh<T> *mesh, void *data) {
323  mesh->SetVertexClientData(id, data);
324  }
325 
326  enum ParentType {
328  };
329 
330 private:
331  // Splits a singular vertex into multiple nonsingular vertices
332  void splitSingular();
333 
334  // Data
335  T data;
336 
337  // Pointer to extra facevarying data. Space for this is allocated
338  // by NewFVarData. This struct is actually overpadded.
339  struct morefvardata {
340  int count;
341  } *morefvar;
342 
343  // Unique ID of this vertex
344  int id;
345 
346  // The number of halfedges which have this vertex as the incident
347  // edge. When references == 0, the vertex is safe to delete
348  int references;
349 
350  // The number of faces marked "used" which share this vertex. May
351  // not be the same as references!
352  int used;
353 
354  // Sharpness
355  float sharpness;
356 
357  // Index of child vertex
358  int vchild;
359 
360  // Size of incident array
361  unsigned short nIncidentEdges;
362 
363  // Vertex masks, at this level of subdivision and at the next
364  // level of subdivision. Valid only when validmask = 1.
365  unsigned short mask0:3;
366  unsigned short mask1:3;
367 
368  // Extraordinary bit
369  unsigned short extraordinary:1;
370  // Whether the current mask value is correct or should be recalculated
371  unsigned short validmask:1;
372  // Whether the vertex is "volatile" (is incident to a semisharp edge,
373  // or is a semisharp corner)
374  unsigned short volatil:1;
375  // Whether we can guarantee the existence of neighboring faces on
376  // this vertex
377  unsigned short neighborsguaranteed:1;
378  // Bookkeeping for HbrMesh
379  unsigned short collected:1;
380 
381  // Whether the vertex has an edit. The edit is owned by a face
382  // so this is just a tag that indicates we need to search the
383  // vertex's neighboring faces for an edit
384  unsigned short hasvertexedit:1;
385  // Whether the vertex edit (if any) has been applied
386  unsigned short editsapplied:1;
387  // Whether Destroy() has been called
388  unsigned short destroyed:1;
389 
390  // Parent type - can be face, edge, or vertex
391  unsigned short parentType:2;
392 
393  // List of edge cycles. For "singular" vertices, the corresponding
394  // set of adjacent halfedges may consist of several cycles, and we
395  // need to account for all of them here. In cases where
396  // nIncidentEdges is 1, the edge field of the union points
397  // directly at the edge which starts the only incident cycle. If
398  // nIncidnetEdges is 2 or more, the edges field of the union is a
399  // separate allocated array and edge member of the array points at
400  // separate cycles.
401  union {
404  } incident;
405 
406  union {
410  } parent;
411 
412 #ifdef HBR_ADAPTIVE
413 public:
414  struct adaptiveFlags {
415  unsigned isTagged:1;
416  unsigned wasTagged:1;
417 
418  adaptiveFlags() : isTagged(0), wasTagged(0) { }
419  };
420 
421  adaptiveFlags _adaptiveFlags;
422 #endif
423 };
424 
425 template <class T>
427  morefvar(0), id(-1), references(0), used(0),
428  sharpness(0.0f), vchild(-1), nIncidentEdges(0), extraordinary(0), validmask(0),
429  volatil(0), neighborsguaranteed(0), collected(0), hasvertexedit(0),
430  editsapplied(0), destroyed(0), parentType(k_ParentNone) {
431  ClearMask();
432  parent.vertex = 0;
433  incident.edge = 0;
434 }
435 
436 template <class T>
437 void
438 HbrVertex<T>::Initialize(int vid, const T &vdata, int fvarwidth) {
439  data = vdata;
440  morefvar = 0 ;
441  id = vid;
442  references = 0;
443  used = 0;
444  extraordinary = 0;
445  ClearMask();
446  neighborsguaranteed = 0;
447  collected = 0;
448  hasvertexedit = 0;
449  editsapplied = 0;
450  destroyed = 0;
451  sharpness = 0.0f;
452  nIncidentEdges = 0;
453  vchild = -1;
454  assert(!parent.vertex);
455  parentType = k_ParentVertex;
456  parent.vertex = 0;
457 
458  if (fvarwidth) {
459  // Upstream allocator ensured the class was padded by the
460  // appropriate size. GetFVarData will return a pointer to this
461  // memory, but it needs to be properly initialized.
462  // Run placement new to initialize datum
463  char *buffer = ((char*) this + sizeof(*this));
464  new (buffer) HbrFVarData<T>();
465  }
466 }
467 
468 template <class T>
470  Destroy();
471 }
472 
473 template <class T>
474 void
476  if (!destroyed) {
477  // Vertices are only safe for deletion if the number of incident
478  // edges is exactly zero.
479  assert(references == 0);
480 
481  // Delete parent reference to self
482  if (parentType == k_ParentEdge && parent.edge) {
483  parent.edge->RemoveChild();
484  parent.edge = 0;
485  } else if (parentType == k_ParentFace && parent.face) {
486  parent.face->RemoveChild();
487  parent.face = 0;
488  } else if (parentType == k_ParentVertex && parent.vertex) {
489  parent.vertex->RemoveChild();
490  parent.vertex = 0;
491  }
492 
493  // Orphan the child vertex
494  if (vchild != -1) {
495  if (mesh) {
496  HbrVertex<T> *vchildVert = mesh->GetVertex(vchild);
497  vchildVert->SetParent(static_cast<HbrVertex*>(0));
498  }
499  vchild = -1;
500  }
501  // We're skipping the placement destructors here, in the
502  // assumption that HbrFVarData's destructor doesn't actually do
503  // anything much
504  if (morefvar) {
505  free(morefvar);
506  }
507  destroyed = 1;
508  }
509 }
510 
511 template <class T>
512 void
514  assert(edge->GetOrgVertex() == this);
515 
516  // First, maintain the property that all of the incident edges
517  // will always be a boundary edge if possible. If any of the
518  // incident edges are no longer boundaries at this point then they
519  // can be immediately removed.
520  int i;
521  unsigned short newEdgeCount = 0;
522  bool edgeFound = false;
523  HbrHalfedge<T>** incidentEdges =
524  (nIncidentEdges > 1) ? incident.edges : &incident.edge;
525 
526  for (i = 0; i < nIncidentEdges; ++i) {
527  if (incidentEdges[i] == edge) {
528  edgeFound = true;
529  }
530  if (incidentEdges[i]->IsBoundary()) {
531  incidentEdges[newEdgeCount++] = incidentEdges[i];
532  } else {
533  // Did this edge suddenly stop being a boundary because
534  // the newly introduced edge (or something close to it)
535  // closed a cycle? If so, we don't want to lose a pointer
536  // to this edge cycle! So check to see if this cycle is
537  // complete, and if so, keep it.
538  HbrHalfedge<T>* start = incidentEdges[i];
539  HbrHalfedge<T>* edge = start;
540  bool prevmatch = false;
541  do {
542  edge = GetNextEdge(edge);
543  // Check all previous incident edges, if already
544  // encountered then we have an edge to this cycle and
545  // don't need to proceed further with this check
546  for (int j = 0; j < i; ++j) {
547  if (incidentEdges[j] == edge) {
548  prevmatch = true;
549  break;
550  }
551  }
552  } while (!prevmatch && edge && edge != start);
553  if (!prevmatch && edge && edge == start) {
554 
555  incidentEdges[newEdgeCount++] = incidentEdges[i];
556  }
557  }
558  }
559 
560  // If we are now left with no incident edges, then this edge
561  // becomes the sole incident edge (since we always need somewhere
562  // to start, even if it's a uninterrupted cycle [ie it doesn't
563  // matter whether the edge is a boundary]). Restore incidentEdges
564  // array to point to the end of the object.
565  if (newEdgeCount == 0) {
566  if (!(edgeFound && nIncidentEdges == 1)) {
567  if (nIncidentEdges > 1) {
568  delete [] incidentEdges;
569  }
570  incidentEdges = &incident.edge;
571  incidentEdges[0] = edge;
572  nIncidentEdges = 1;
573  }
574  }
575 
576  // Otherwise, we already have a set of incident edges - we only
577  // add this edge if it's a boundary edge, which would begin a new
578  // cycle.
579  else if (edge->IsBoundary()) {
580  if (!edgeFound) {
581  // Must add the new edge. May need to reallocate here.
582  if (newEdgeCount + 1 != nIncidentEdges) {
583  HbrHalfedge<T>** newIncidentEdges = 0;
584  if (newEdgeCount + 1 > 1) {
585  newIncidentEdges = new HbrHalfedge<T>*[newEdgeCount + 1];
586  } else {
587  newIncidentEdges = &incident.edge;
588  }
589  for (i = 0; i < newEdgeCount; ++i) {
590  newIncidentEdges[i] = incidentEdges[i];
591  }
592  if (nIncidentEdges > 1) {
593  delete[] incidentEdges;
594  }
595  nIncidentEdges = newEdgeCount + 1;
596  incidentEdges = newIncidentEdges;
597  if (nIncidentEdges > 1) {
598  incident.edges = newIncidentEdges;
599  }
600  }
601  incidentEdges[newEdgeCount] = edge;
602  } else {
603  // Edge is already in our list, so we don't need to add it
604  // again. However, we may need to reallocate due to above
605  // cleaning of nonboundary edges
606  if (newEdgeCount != nIncidentEdges) {
607  HbrHalfedge<T>** newIncidentEdges = 0;
608  if (newEdgeCount > 1) {
609  newIncidentEdges = new HbrHalfedge<T>*[newEdgeCount];
610  } else {
611  newIncidentEdges = &incident.edge;
612  }
613  for (i = 0; i < newEdgeCount; ++i) {
614  newIncidentEdges[i] = incidentEdges[i];
615  }
616  if (nIncidentEdges > 1) {
617  delete[] incidentEdges;
618  }
619  nIncidentEdges = newEdgeCount;
620  incidentEdges = newIncidentEdges;
621  if (nIncidentEdges > 1) {
622  incident.edges = newIncidentEdges;
623  }
624  }
625  }
626  }
627  else {
628  // Again, we may need to reallocate due to above cleaning of
629  // nonboundary edges
630  if (newEdgeCount != nIncidentEdges) {
631  HbrHalfedge<T>** newIncidentEdges = 0;
632  if (newEdgeCount > 1) {
633  newIncidentEdges = new HbrHalfedge<T>*[newEdgeCount];
634  } else {
635  newIncidentEdges = &incident.edge;
636  }
637  for (i = 0; i < newEdgeCount; ++i) {
638  newIncidentEdges[i] = incidentEdges[i];
639  }
640  if (nIncidentEdges > 1) {
641  delete[] incidentEdges;
642  }
643  nIncidentEdges = newEdgeCount;
644  incidentEdges = newIncidentEdges;
645  if (nIncidentEdges > 1) {
646  incident.edges = newIncidentEdges;
647  }
648  }
649  }
650 
651  // For non-boundary edges, ensure that the incident edge starting
652  // the cycle is the lowest possible edge. By doing this,
653  // operations like GetSurroundingEdges will be guaranteed to
654  // return the same order of edges/faces through multi-threading.
655  if (!incidentEdges[0]->IsBoundary()) {
656  HbrHalfedge<T>* start = GetIncidentEdge();
657  incidentEdges[0] = start;
658  HbrFacePath incidentEdgePath = incidentEdges[0]->GetFace()->GetPath();
659  HbrHalfedge<T>* e = GetNextEdge(start);
660  while (e) {
661  if (e == start) break;
662  HbrFacePath ePath = e->GetFace()->GetPath();
663  if (ePath < incidentEdgePath) {
664  incidentEdges[0] = e;
665  incidentEdgePath = ePath;
666  }
667  HbrHalfedge<T>* next = GetNextEdge(e);
668  if (!next) {
669  e = e->GetPrev();
670  if (e->GetFace()->GetPath() < incidentEdges[0]->GetFace()->GetPath()) {
671  incidentEdges[0] = e;
672  }
673  break;
674  } else {
675  e = next;
676  }
677  }
678  }
679 
680  references++;
681 }
682 
683 template <class T>
684 void
686 
687  int i, j;
688  HbrHalfedge<T>** incidentEdges =
689  (nIncidentEdges > 1) ? incident.edges : &incident.edge;
690 
691  references--;
692  if (references) {
693 
694  HbrHalfedge<T>* next;
695 
696  // We may need to shuffle our halfedge cycles. First we check
697  // whether the edge being erased begins any edge cycles
698  bool edgeFound = false;
699  next = GetNextEdge(edge);
700 
701  for (i = 0; i < nIncidentEdges; ++i) {
702  if (incidentEdges[i] == edge) {
703 
704  // Edge cycle found. Replace the edge with the next edge
705  // in the cycle if possible.
706  if (next) {
707  incidentEdges[i] = next;
708  // We are done.
709  return;
710  }
711 
712  // If no next edge is found it means the entire cycle
713  // has gone away.
714  edgeFound = true;
715  break;
716  }
717  }
718 
719  // The edge cycle needs to disappear
720  if (edgeFound) {
721  assert(nIncidentEdges > 1);
722 
723  HbrHalfedge<T>** newIncidentEdges = 0;
724  if (nIncidentEdges - 1 > 1) {
725  newIncidentEdges = new HbrHalfedge<T>*[nIncidentEdges - 1];
726  } else {
727  newIncidentEdges = &incident.edge;
728  }
729  j = 0;
730  for (i = 0; i < nIncidentEdges; ++i) {
731  if (incidentEdges[i] != edge) {
732  newIncidentEdges[j++] = incidentEdges[i];
733  }
734  }
735  assert(j == nIncidentEdges - 1);
736  if (nIncidentEdges > 1) {
737  delete[] incidentEdges;
738  }
739  nIncidentEdges--;
740  if (nIncidentEdges > 1) {
741  incident.edges = newIncidentEdges;
742  }
743  return;
744  }
745  // Now deal with the case where we remove an edge
746  // which did not begin a boundary edge cycle. If this
747  // happens then the resulting unbroken cycle does
748  // get broken; in that case we replace the incident
749  // edge with the next one after this.
750  else if (nIncidentEdges == 1 && !incidentEdges[0]->IsBoundary()) {
751  if (next) {
752  incidentEdges[0] = next;
753  } else {
754  // hm, what does this mean for us? Not sure at the
755  // moment.
756  std::cout << "Could not split cycle!\n";
757  assert(0);
758  }
759  }
760 
761  // (Is this another case or a specialization of the above?)
762  // When an edge in the middle of a boundary cycle goes away we
763  // need to mark a new cycle.
764  //
765  // If there is no next edge, it means that we didn't
766  // actually split the cycle, we just deleted the last edge
767  // in the cycle. As such nothing needs to occur because
768  // the "split" is already present.
769 
770  else if (!edge->IsBoundary() && next) {
771  HbrHalfedge<T>** newIncidentEdges = 0;
772  if (nIncidentEdges + 1 > 1) {
773  newIncidentEdges = new HbrHalfedge<T>*[nIncidentEdges + 1];
774  } else {
775  newIncidentEdges = &incident.edge;
776  }
777  for (i = 0; i < nIncidentEdges; ++i) {
778  newIncidentEdges[i] = incidentEdges[i];
779  }
780  newIncidentEdges[nIncidentEdges] = next;
781  if (nIncidentEdges > 1) {
782  delete[] incidentEdges;
783  }
784  nIncidentEdges++;
785  if (nIncidentEdges > 1) {
786  incident.edges = newIncidentEdges;
787  }
788  }
789  } else {
790  // No references left, we can just clear all the cycles
791  if (nIncidentEdges > 1) {
792  delete[] incidentEdges;
793  }
794  nIncidentEdges = 0;
795  }
796 }
797 
798 template <class T>
799 bool
801  // Only edge left, or no incident edges at all (how?)
802  if (references <= 1 || nIncidentEdges <= 0) {
803  return false;
804  }
805  // There are at least two existing cycles. We could maybe consider
806  // the case where removal of this edge will actually make one of
807  // the edge cycles go away, possibly leaving behind just one, but
808  // we'll ignore that possibility for now
809  else if (nIncidentEdges > 1) {
810  return true;
811  }
812  // This is the incident edge starting a single cycle. Removal of
813  // the edge will replace the start of the cycle with the next
814  // edge, and we keep a single cycle.
815  else if (nIncidentEdges == 1 && incident.edge == edge) {
816  return false;
817  }
818  // Check the single cycle: was it interrupted? (i.e. a
819  // boundary). If not interrupted, then deletion of any edge still
820  // leaves a single cycle. Otherwise: if the edge is the *last*
821  // edge in the cycle, we still don't need to split the any further
822  // cycle. Otherwise we must split the cycle, which would result in
823  // a singular vertex
824  else if (!GetIncidentEdge()->IsBoundary()) {
825  return false;
826  } else if (GetNextEdge(edge)) {
827  return true;
828  } else {
829  return false;
830  }
831 }
832 
833 template <class T>
834 void
836  extraordinary = false;
837  if (HbrMesh<T>* mesh = GetMesh()) {
838  if (IsSingular()) splitSingular();
839  assert(!IsSingular());
840  if (mesh->GetSubdivision()) {
841  extraordinary = mesh->GetSubdivision()->VertexIsExtraordinary(mesh, this);
842  }
843  }
844 }
845 
846 template <class T>
847 int
849  int valence = 0;
850  assert(!IsSingular());
851  HbrHalfedge<T>* start =
852  (nIncidentEdges > 1) ? incident.edges[0] : incident.edge;
853  HbrHalfedge<T>* edge = start;
854  if (edge) do {
855  valence++;
856  edge = GetNextEdge(edge);
857  } while (edge && edge != start);
858  // In boundary cases, we increment the valence count by
859  // one more
860  if (!edge) valence++;
861  return valence;
862 }
863 
864 template <class T>
865 int
867  int valence = 0;
868  assert(!IsSingular());
869  HbrHalfedge<T>* start =
870  (nIncidentEdges > 1) ? incident.edges[0] : incident.edge;
871  HbrHalfedge<T>* edge = start;
872  if (edge) do {
873  if (edge->IsCoarse()) {
874  valence++;
875  }
876  edge = GetNextEdge(edge);
877  } while (edge && edge != start);
878  // In boundary cases, we increment the valence count by one more
879  // (this assumes the last edge is coarse, which it had better be
880  // in the boundary case!)
881  if (!edge) valence++;
882  return valence;
883 }
884 
885 template <class T>
888  // See if there are any extra facevarying datum associated with
889  // this vertex, and whether any of them match the face.
890  if (morefvar) {
891  size_t fvtsize = sizeof(HbrFVarData<T>) + sizeof(float) * (GetMesh()->GetTotalFVarWidth() - 1);
892  HbrFVarData<T> *fvt = (HbrFVarData<T> *)((char *) morefvar + sizeof(int));
893  for (int i = 0; i < morefvar->count; ++i) {
894  if (fvt->GetFaceID() == face->GetID()) {
895  return *fvt;
896  }
897  fvt = (HbrFVarData<T>*)((char*) fvt + fvtsize);
898  }
899  }
900  // Otherwise, return the default facevarying datum, which lives
901  // in the overallocated space after the end of this object
902  return *((HbrFVarData<T>*) ((char*) this + sizeof(*this)));
903 }
904 
905 template <class T>
908  const int fvarwidth = GetMesh()->GetTotalFVarWidth();
909  size_t fvtsize = sizeof(HbrFVarData<T>) + (fvarwidth - 1) * sizeof(float);
910  if (morefvar) {
911  struct morefvardata *newmorefvar =
912  (struct morefvardata *) malloc(sizeof(int) + (morefvar->count + 1) * fvtsize);
913  HbrFVarData<T> *newfvt = (HbrFVarData<T> *)((char *) newmorefvar + sizeof(int));
914  HbrFVarData<T> *oldfvt = (HbrFVarData<T> *)((char *) morefvar + sizeof(int));
915  for (int i = 0; i < morefvar->count; ++i) {
916  new (newfvt) HbrFVarData<T>();
917  newfvt->SetAllData(fvarwidth, oldfvt->GetData(0));
918  newfvt->SetFaceID(oldfvt->GetFaceID());
919  oldfvt = (HbrFVarData<T>*)((char*) oldfvt + fvtsize);
920  newfvt = (HbrFVarData<T>*)((char*) newfvt + fvtsize);
921  }
922  new (newfvt) HbrFVarData<T>();
923  newfvt->SetFaceID(face->GetID());
924  newmorefvar->count = morefvar->count + 1;
925  free(morefvar);
926  morefvar = newmorefvar;
927  return *newfvt;
928  } else {
929  morefvar = (struct morefvardata *) malloc(sizeof(int) + fvtsize);
930  HbrFVarData<T> *newfvt = (HbrFVarData<T> *)((char *) morefvar + sizeof(int));
931  new (newfvt) HbrFVarData<T>();
932  newfvt->SetFaceID(face->GetID());
933  morefvar->count = 1;
934  return *newfvt;
935  }
936 }
937 
938 
939 
940 template <class T>
941 HbrFace<T>*
943  return GetIncidentEdge()->GetFace();
944 }
945 
946 template <class T>
947 HbrMesh<T>*
949  return GetFace()->GetMesh();
950 }
951 
952 template <class T>
955  // Here, we generally want to go through all halfedge cycles
956  for (int i = 0; i < nIncidentEdges; ++i) {
957  HbrHalfedge<T>* cycle =
958  (nIncidentEdges > 1) ? incident.edges[i] : incident.edge;
959  HbrHalfedge<T>* edge = cycle;
960  if (edge) do {
961  if (edge->GetDestVertex() == dest) {
962  return edge;
963  }
964  edge = GetNextEdge(edge);
965  } while (edge && edge != cycle);
966  }
967  return 0;
968 }
969 
970 template <class T>
972 HbrVertex<T>::GetEdge(int dest) const {
973  // Here, we generally want to go through all halfedge cycles
974  for (int i = 0; i < nIncidentEdges; ++i) {
975  HbrHalfedge<T>* cycle =
976  (nIncidentEdges > 1) ? incident.edges[i] : incident.edge;
977  HbrHalfedge<T>* edge = cycle;
978  if (edge) do {
979  if (edge->GetDestVertexID() == dest) {
980  return edge;
981  }
982  edge = GetNextEdge(edge);
983  } while (edge && edge != cycle);
984  }
985  return 0;
986 }
987 
988 template <class T>
991  // Paranoia:
992  // if (edge->GetOrgVertex() != this) return 0;
993  return edge->GetPrev()->GetOpposite();
994 }
995 
996 template <class T>
999  // Paranoia:
1000  // if (edge->GetOrgVertex() != this) return 0;
1001  return edge->GetOpposite()->GetNext();
1002 }
1003 
1004 template <class T>
1005 HbrVertex<T>*
1007  HbrHalfedge<T>* edge = GetEdge(dest);
1008  if (edge) {
1009  return edge->GetPrev()->GetOrgVertex();
1010  }
1011  HbrHalfedge<T>* start = GetIncidentEdge(), *next;
1012  edge = start;
1013  while (edge) {
1014  next = GetNextEdge(edge);
1015  if (edge->GetDestVertex() == dest) {
1016  if (!next) {
1017  return edge->GetPrev()->GetOrgVertex();
1018  } else {
1019  return next->GetDestVertex();
1020  }
1021  }
1022  if (next == start) {
1023  return 0;
1024  } else if (!next) {
1025  if (edge->GetPrev()->GetOrgVertex() == dest) {
1026  return start->GetDestVertex();
1027  } else {
1028  return 0;
1029  }
1030  } else {
1031  edge = next;
1032  }
1033  }
1034  // Shouldn't get here
1035  return 0;
1036 }
1037 
1038 template <class T>
1039 HbrVertex<T>*
1041  assert(edge->GetOrgVertex() == this);
1042  return edge->GetPrev()->GetOrgVertex();
1043 }
1044 
1045 template <class T>
1046 HbrVertex<T>*
1048  HbrHalfedge<T>* edge = GetEdge(dest);
1049  if (edge) {
1050  if (edge->GetOpposite()) {
1051  return edge->GetOpposite()->GetNext()->GetDestVertex();
1052  } else {
1053  HbrHalfedge<T>* start = GetIncidentEdge(), *next;
1054  edge = start;
1055  while (edge) {
1056  next = GetNextEdge(edge);
1057  if (next == start) {
1058  if (next->GetDestVertex() == dest) {
1059  return edge->GetDestVertex();
1060  } else {
1061  return 0;
1062  }
1063  } else if (!next) {
1064  if (edge->GetPrev()->GetOrgVertex() == dest) {
1065  return edge->GetDestVertex();
1066  } else if (start->GetDestVertex() == dest) {
1067  return edge->GetPrev()->GetOrgVertex();
1068  } else {
1069  return 0;
1070  }
1071  } else if (next->GetDestVertex() == dest) {
1072  return edge->GetDestVertex();
1073  } else {
1074  edge = next;
1075  }
1076  }
1077  return 0;
1078  }
1079  }
1080  edge = dest->GetEdge(this);
1081  if (edge) {
1082  return edge->GetNext()->GetDestVertex();
1083  }
1084  return 0;
1085 }
1086 
1087 template <class T>
1088 HbrVertex<T>*
1090  assert(edge->GetOrgVertex() == this);
1091  if (edge->GetOpposite()) {
1092  return edge->GetOpposite()->GetNext()->GetDestVertex();
1093  } else {
1094  return GetQEOPrev(edge->GetDestVertex());
1095  }
1096 }
1097 
1098 template <class T>
1099 HbrVertex<T>*
1101  HbrHalfedge<T>* edge = GetEdge(dest);
1102  if (edge) {
1103  return edge->GetNext()->GetDestVertex();
1104  }
1105  edge = dest->GetEdge(this);
1106  if (edge) {
1107  return edge->GetPrev()->GetOrgVertex();
1108  }
1109  return 0;
1110 }
1111 
1112 template <class T>
1113 bool
1115  // We really only need to check the first incident edge, since
1116  // singular vertices by definition are on the boundary
1117  return GetIncidentEdge()->IsBoundary();
1118 }
1119 
1120 template <class T>
1121 bool
1123  return (GetFVarMask(datum) == k_Smooth);
1124 }
1125 
1126 template <class T>
1127 bool
1129  for (int i = 0; i < GetMesh()->GetFVarCount(); ++i) {
1130  if (!IsFVarSmooth(i)) return false;
1131  }
1132  return true;
1133 }
1134 
1135 template <class T>
1136 bool
1138  return (GetFVarMask(datum) == k_Dart);
1139 }
1140 
1141 template <class T>
1142 bool
1144 
1145  // If it's a dart, it's a corner
1146  if (IsFVarDart(datum)) return true;
1147 
1148  // Run through surrounding edges, looking for two adjacent
1149  // facevarying boundary edges
1150  HbrHalfedge<T>* start = GetIncidentEdge(), *edge, *nextedge;
1151  edge = start;
1152  bool lastedgewassharp = false;
1153  while (edge) {
1154  if (edge->GetFVarSharpness(datum)) {
1155  if (lastedgewassharp) {
1156  return true;
1157  } else {
1158  lastedgewassharp = true;
1159  }
1160  } else {
1161  lastedgewassharp = false;
1162  }
1163  nextedge = GetNextEdge(edge);
1164  if (nextedge == start) {
1165  return start->GetFVarSharpness(datum) && lastedgewassharp;
1166  } else if (!nextedge) {
1167  // Special case for the last edge in a cycle.
1168  edge = edge->GetPrev();
1169  return edge->GetFVarSharpness(datum) && lastedgewassharp;
1170  } else {
1171  edge = nextedge;
1172  }
1173  }
1174  return false;
1175 }
1176 
1177 template <class T>
1178 unsigned char
1180 
1181  if (validmask) {
1182  return (unsigned char)(next ? mask1 : mask0);
1183  }
1184 
1185  mask0 = mask1 = 0;
1186 
1187  // Mark volatility
1188  if (sharpness > k_Smooth && sharpness < k_InfinitelySharp)
1189  volatil = 1;
1190 
1191  // If the vertex is tagged as sharp immediately promote its mask
1192  // to corner
1193  if (IsSharp(false)) {
1194  mask0 += k_Corner;
1195  }
1196  if (IsSharp(true)) {
1197  mask1 += k_Corner;
1198  }
1199 
1200  // Count the number of surrounding sharp edges
1201  HbrHalfedge<T>* start = GetIncidentEdge(), *edge, *nextedge;
1202  edge = start;
1203  while (edge) {
1204  float esharp = edge->GetSharpness();
1205 
1206  if (edge->IsSharp(false)) {
1207  if (mask0 < k_Corner) {
1208  mask0++;
1209  }
1210  }
1211  if (edge->IsSharp(true)) {
1212  if (mask1 < k_Corner) {
1213  mask1++;
1214  }
1215  }
1216  // If any incident edge is semisharp, mark the vertex as volatile
1218  volatil = 1;
1219  }
1220  nextedge = GetNextEdge(edge);
1221  if (nextedge == start) {
1222  break;
1223  } else if (!nextedge) {
1224  // Special case for the last edge in a cycle.
1225  edge = edge->GetPrev();
1226  esharp = edge->GetSharpness();
1227  if (edge->IsSharp(false)) {
1228  if (mask0 < k_Corner) {
1229  mask0++;
1230  }
1231  }
1232  if (edge->IsSharp(true)) {
1233  if (mask1 < k_Corner) {
1234  mask1++;
1235  }
1236  }
1238  volatil = 1;
1239  }
1240  break;
1241  } else {
1242  edge = nextedge;
1243  }
1244  }
1245  validmask = 1;
1246  return (unsigned char)(next ? mask1 : mask0);
1247 }
1248 
1249 template <class T>
1250 unsigned char
1252 
1253  unsigned char mask = 0;
1254 
1255  // If the vertex is tagged as sharp immediately promote its mask
1256  // to corner
1257  if (IsSharp(false)) {
1258  mask += k_Corner;
1259  }
1260 
1261  // Count the number of surrounding facevarying boundary edges
1262  HbrHalfedge<T>* start = GetIncidentEdge(), *edge, *nextedge;
1263  edge = start;
1264  while (edge) {
1265  if (edge->GetFVarSharpness(datum)) {
1266  if (mask < k_Corner) {
1267  mask++;
1268  } else {
1269  // Can't get any sharper, so give up early
1270  break;
1271  }
1272  }
1273  nextedge = GetNextEdge(edge);
1274  if (nextedge == start) {
1275  break;
1276  } else if (!nextedge) {
1277  // Special case for the last edge in a cycle.
1278  edge = edge->GetPrev();
1279  if (edge->GetFVarSharpness(datum)) {
1280  if (mask < k_Corner) {
1281  mask++;
1282  }
1283  }
1284  break;
1285  } else {
1286  edge = nextedge;
1287  }
1288  }
1289  return mask;
1290 }
1291 
1292 template <class T>
1293 float
1295  float mask = 0;
1296  float n = 0;
1297 
1298  if (sharpness > k_Smooth && sharpness < k_Dart) {
1299  mask += sharpness; ++n;
1300  }
1301 
1302  // Add up the strengths of surrounding fractional sharp edges
1303  HbrHalfedge<T>* start = GetIncidentEdge(), *edge, *next;
1304  edge = start;
1305  while (edge) {
1306  float esharp = edge->GetSharpness();
1307  if (esharp > HbrHalfedge<T>::k_Smooth && esharp < HbrHalfedge<T>::k_Sharp) {
1308  mask += esharp; ++n;
1309  }
1310  next = GetNextEdge(edge);
1311  if (next == start) {
1312  break;
1313  } else if (!next) {
1314  // Special case for the last edge in a cycle.
1315  esharp = edge->GetPrev()->GetSharpness();
1316  if (esharp > HbrHalfedge<T>::k_Smooth && esharp < HbrHalfedge<T>::k_Sharp) {
1317  mask += esharp; ++n;
1318  }
1319  break;
1320  } else {
1321  edge = next;
1322  }
1323  }
1324  assert (n > 0.0f && mask < n);
1325  return (mask / n);
1326 }
1327 
1328 template <class T>
1329 template <typename OutputIterator>
1330 void
1331 HbrVertex<T>::GetSurroundingEdges(OutputIterator edges) const {
1332  HbrHalfedge<T>* start = GetIncidentEdge(), *edge, *next;
1333  edge = start;
1334  while (edge) {
1335  *edges++ = edge;
1336  next = GetNextEdge(edge);
1337  if (next == start) {
1338  break;
1339  } else if (!next) {
1340  // Special case for the last edge in a cycle.
1341  *edges++ = edge->GetPrev();
1342  break;
1343  } else {
1344  edge = next;
1345  }
1346  }
1347 }
1348 
1349 template <class T>
1350 void
1352  HbrHalfedge<T>* start = GetIncidentEdge(), *edge, *next;
1353  edge = start;
1354  while (edge) {
1355  op(*edge);
1356  next = GetNextEdge(edge);
1357  if (next == start) {
1358  break;
1359  } else if (!next) {
1360  op(*edge->GetPrev());
1361  break;
1362  } else {
1363  edge = next;
1364  }
1365  }
1366 }
1367 
1368 template <class T>
1369 template <typename OutputIterator>
1370 void
1371 HbrVertex<T>::GetSurroundingVertices(OutputIterator vertices) const {
1372  HbrMesh<T>* mesh = GetMesh();
1373  HbrHalfedge<T>* start = GetIncidentEdge(), *edge, *next;
1374  edge = start;
1375  while (edge) {
1376  *vertices++ = edge->GetDestVertex(mesh);
1377  next = GetNextEdge(edge);
1378  if (next == start) {
1379  break;
1380  } else if (!next) {
1381  // Special case for the last edge in a cycle: the last
1382  // vertex on that cycle is not the destination of an
1383  // outgoing halfedge
1384  *vertices++ = edge->GetPrev()->GetOrgVertex(mesh);
1385  break;
1386  } else {
1387  edge = next;
1388  }
1389  }
1390 }
1391 
1392 template <class T>
1393 void
1395  HbrMesh<T>* mesh = GetMesh();
1396  HbrHalfedge<T>* start = GetIncidentEdge(), *edge, *next;
1397  edge = start;
1398  while (edge) {
1399  op(*edge->GetDestVertex(mesh));
1400  next = GetNextEdge(edge);
1401  if (next == start) return;
1402  else if (!next) {
1403  op(*edge->GetPrev()->GetOrgVertex(mesh));
1404  return;
1405  } else {
1406  edge = next;
1407  }
1408  }
1409 }
1410 
1411 template <class T>
1412 void
1414  HbrHalfedge<T>* start = GetIncidentEdge(), *edge;
1415  edge = start;
1416  while (edge) {
1417  op(*edge->GetLeftFace());
1418  edge = GetNextEdge(edge);
1419  if (edge == start) break;
1420  }
1421 }
1422 
1423 template <class T>
1424 HbrVertex<T>*
1426  HbrMesh<T>* mesh = GetMesh();
1427  if (vchild != -1) return mesh->GetVertex(vchild);
1428  HbrVertex<T>* vchildVert = mesh->GetSubdivision()->Subdivide(mesh, this);
1429  vchild = vchildVert->GetID();
1430  vchildVert->SetParent(this);
1431  return vchildVert;
1432 }
1433 
1434 template <class T>
1435 void
1437  HbrMesh<T>* mesh = GetMesh();
1438  mesh->GetSubdivision()->RefineAtVertex(mesh, this);
1439 }
1440 
1441 template <class T>
1442 void
1444  if (!neighborsguaranteed) {
1445  HbrMesh<T>* mesh = GetMesh();
1446  mesh->GetSubdivision()->GuaranteeNeighbors(mesh, this);
1447  neighborsguaranteed = 1;
1448 
1449  // At this point we can apply vertex edits because we have all
1450  // surrounding faces, and know whether any of them has
1451  // necessary edit information (they would have set our
1452  // hasvertexedit bit)
1453  if (hasvertexedit && !editsapplied) {
1454  HbrHalfedge<T>* start = GetIncidentEdge(), *edge;
1455  edge = start;
1456  while (edge) {
1457  HbrFace<T>* face = edge->GetLeftFace();
1458  if (HbrHierarchicalEdit<T>** edits = face->GetHierarchicalEdits()) {
1459  while (HbrHierarchicalEdit<T>* edit = *edits) {
1460  if (!edit->IsRelevantToFace(face)) break;
1461  edit->ApplyEditToVertex(face, this);
1462  edits++;
1463  }
1464  }
1465  edge = GetNextEdge(edge);
1466  if (edge == start) break;
1467  }
1468  editsapplied = 1;
1469  }
1470  }
1471 }
1472 
1473 template <class T>
1474 unsigned long
1476  return sizeof(HbrVertex<T>);
1477 }
1478 
1479 
1480 template <class T>
1481 void
1483  HbrMesh<T>* mesh = GetMesh();
1484  HbrHalfedge<T>* e;
1485  HbrHalfedge<T>** incidentEdges =
1486  (nIncidentEdges > 1) ? incident.edges : &incident.edge;
1487 
1488  // Go through each edge cycle after the first
1489  std::vector<HbrHalfedge<T>*> edges;
1490  for (int i = 1; i < nIncidentEdges; ++i) {
1491 
1492  // Create duplicate vertex
1493  HbrVertex<T>* w = mesh->NewVertex();
1494  w->GetData().AddWithWeight(GetData(), 1.0);
1495  w->SetSharpness(GetSharpness());
1496 
1497  // Walk all edges in this cycle and reattach them to duplicate
1498  // vertex
1499  HbrHalfedge<T>* start = incidentEdges[i];
1500  e = start;
1501  edges.clear();
1502  do {
1503  edges.push_back(e);
1504  e = GetNextEdge(e);
1505  } while (e && e != start);
1506 
1507  for (typename std::vector<HbrHalfedge<T>*>::iterator ei = edges.begin(); ei != edges.end(); ++ei) {
1508  e = *ei;
1509  if (e->GetOpposite()) {
1510  HbrHalfedge<T>* next = e->GetOpposite()->GetNext();
1511  if (next->GetOrgVertex() == this) {
1512  references--;
1513  next->SetOrgVertex(w);
1514  w->AddIncidentEdge(next);
1515  }
1516  }
1517  // Check again, because sometimes it's been relinked by
1518  // previous clause already
1519  if (e->GetOrgVertex() == this) {
1520  references--;
1521  e->SetOrgVertex(w);
1522  w->AddIncidentEdge(e);
1523  }
1524  }
1525  w->Finish();
1526 #ifdef HBR_ADAPTIVE
1527  mesh->addSplitVertex(w->GetID(), this->GetID());
1528 #endif
1529  }
1530 
1531  e = incidentEdges[0];
1532  if (nIncidentEdges > 1) {
1533  delete[] incidentEdges;
1534  }
1535  nIncidentEdges = 1;
1536  incident.edge = e;
1537 }
1538 
1539 template <class T>
1540 std::ostream&
1541 operator<<(std::ostream& out, const HbrVertex<T>& vertex) {
1542  return out << "vertex " << vertex.GetID();
1543 }
1544 
1545 template <class T>
1546 class HbrVertexOperator {
1547 public:
1548  virtual void operator() (HbrVertex<T> &vertex) = 0;
1549  virtual ~HbrVertexOperator() {}
1550 };
1551 
1552 } // end namespace OPENSUBDIV_VERSION
1553 using namespace OPENSUBDIV_VERSION;
1554 
1555 } // end namespace OpenSubdiv
1556 
1557 #endif /* HBRVERTEX_H */
1558 
1559 
void RemoveIncidentEdge(HbrHalfedge< T > *edge)
Definition: vertex.h:685
HbrFVarData< T > & NewFVarData(const HbrFace< T > *face)
Definition: vertex.h:907
void SetVertexClientData(int id, void *data)
Definition: mesh.h:97
HbrVertex< T > * NewVertex(int id, const T &data)
Definition: mesh.h:533
void SetParent(HbrFace< T > *face)
Definition: vertex.h:226
HbrVertex< T > * GetVertex(int id) const
Definition: mesh.h:79
void ApplyOperatorSurroundingVertices(HbrVertexOperator< T > &op) const
Definition: vertex.h:1394
bool EdgeRemovalWillMakeSingular(HbrHalfedge< T > *edge) const
Definition: vertex.h:800
unsigned char GetMask(bool next)
Definition: vertex.h:1179
HbrHalfedge< T > * GetEdge(const HbrVertex< T > *dest) const
Definition: vertex.h:954
void GetSurroundingEdges(OutputIterator edges) const
Definition: vertex.h:1331
void * GetVertexClientData(int id) const
Definition: mesh.h:88
HbrHalfedge< T > * GetNext() const
Definition: halfedge.h:80
HbrVertex< T > * GetDestVertex() const
Definition: halfedge.h:143
HbrHalfedge< T > * GetPreviousEdge(const HbrHalfedge< T > *edge) const
Definition: vertex.h:998
HbrFace< T > * GetParentFace() const
Definition: vertex.h:221
virtual void operator()(HbrVertex< T > &vertex)=0
HbrSubdivision< T > * GetSubdivision() const
Definition: mesh.h:178
float GetFVarSharpness(int datum, bool ignoreGeometry=false)
Definition: halfedge.h:684
HbrHierarchicalEdit< T > ** GetHierarchicalEdits() const
Definition: face.h:244
HbrMesh< T > * GetMesh() const
Definition: vertex.h:948
HbrVertex< T > * GetParentVertex() const
Definition: vertex.h:222
unsigned char GetFVarMask(int datum)
Definition: vertex.h:1251
HbrHalfedge< T > * GetIncidentEdge() const
Definition: vertex.h:285
HbrVertex< T > * GetQEOPrev(const HbrHalfedge< T > *edge) const
Definition: vertex.h:1089
HbrFace< T > * GetFace() const
Definition: vertex.h:942
HbrHalfedge< T > * GetNextEdge(const HbrHalfedge< T > *edge) const
Definition: vertex.h:990
HbrHalfedge< T > * GetOpposite() const
Definition: halfedge.h:74
void GetSurroundingVertices(OutputIterator vertices) const
Definition: vertex.h:1371
HbrVertex< T > * GetOrgVertex() const
Definition: halfedge.h:125
bool IsSharp(bool next) const
Definition: vertex.h:167
void SetParent(HbrHalfedge< T > *edge)
Definition: vertex.h:225
void ApplyOperatorSurroundingFaces(HbrFaceOperator< T > &op) const
Definition: vertex.h:1413
HbrVertex(int vid, const T &data, int fvarwidth)
Definition: vertex.h:51
void SetParent(HbrVertex< T > *vertex)
Definition: vertex.h:227
void Destroy(HbrMesh< T > *mesh=0)
Definition: vertex.h:475
void * GetClientData(HbrMesh< T > *mesh) const
Definition: vertex.h:317
void Initialize(int vid, const T &data, int fvarwidth)
Definition: vertex.h:438
HbrHalfedge< T > * GetParentEdge() const
Definition: vertex.h:220
void SetClientData(HbrMesh< T > *mesh, void *data)
Definition: vertex.h:322
void ApplyOperatorSurroundingEdges(HbrHalfedgeOperator< T > &op) const
Definition: vertex.h:1351
unsigned long GetMemStats() const
Definition: vertex.h:1475
void SetAllData(int width, const float *values)
Definition: fvarData.h:139
void SetOrgVertex(HbrVertex< T > *v)
Definition: halfedge.h:140
HbrVertex< T > * GetQEONext(const HbrVertex< T > *dest) const
Definition: vertex.h:1006
HbrVertex< T > * GetQELNext(const HbrVertex< T > *dest) const
Definition: vertex.h:1100
HbrHalfedge< T > * GetPrev() const
Definition: halfedge.h:98
HbrFVarData< T > & GetFVarData(const HbrFace< T > *face)
Definition: vertex.h:887
void AddIncidentEdge(HbrHalfedge< T > *edge)
Definition: vertex.h:513