Commit 74036c1b authored by David Thompson's avatar David Thompson
Browse files

Progress on face creation.

parent 86fe3ff9
......@@ -207,8 +207,22 @@ struct EdgeFragment
internal::EdgePtr m_edgeData; // Private edge data (sequence of points defining segments)
int m_segment; // Offset into edge's point sequence defining the segment containing this fragment.
bool m_sense; // True when fragment and model edge are codirectional; false when they are antidirectional.
RegionIdSet::value_type m_regionId[2]; // Union-Find region to each side of edge; 0: region CCW of edge, 1: region CW of edge.
RegionId m_regionId[2]; // Union-Find region to each side of edge; 0: region CCW of edge, 1: region CW of edge.
FragmentId m_next[2]; // Next co-fragment in region; 0: opposite of fragment dir, 1: along fragment dir.
int m_marked[2]; // Has this co-edge been output?
EdgeFragment()
{
for (int i = 0; i < 2; ++i)
{
this->m_regionId[i] = -1;
this->m_marked[i] = 0;
this->m_next[i] = -1;
}
}
smtk::model::Edge edge() const { return this->m_edge; }
bool orientation() const { return this->m_sense; }
internal::Point& lo() { return this->m_lo; }
const internal::Point& lo() const { return this->m_lo; }
......@@ -218,27 +232,50 @@ struct EdgeFragment
/// Return the ID of the region above the fragment.
RegionIdSet::value_type& upperRegion() { return this->m_regionId[1]; }
RegionIdSet::value_type upperRegion() const { return this->m_regionId[1]; }
/// Return the ID of the region below the fragment.
RegionIdSet::value_type& lowerRegion() { return this->m_regionId[0]; }
RegionIdSet::value_type lowerRegion() const { return this->m_regionId[0]; }
/**\brief Return the ID of the region just counter-clockwise (CCW) of the fragment...
*
* ... when winding around the lower (\a fromLowerEnd is true) or
* upper (\a fromLowerEnd is false) endpoint of the fragment.
*
* You can also think of \a fromLowerEnd as representing the
* orientation of the co-fragment you wish to consider;
* calling ccwRegion(false) returns ID of the region to the
* left of the reversed co-fragment (from hi() to lo()) while
* calling ccwRegion(true) returns ID of the region to the
* left of the forward co-fragment (from lo() to hi()).
*/
RegionIdSet::value_type& ccwRegion(bool fromLowerEnd) { return this->m_regionId[fromLowerEnd ? 1 : 0]; }
RegionIdSet::value_type ccwRegion(bool fromLowerEnd) const { return this->m_regionId[fromLowerEnd ? 1 : 0]; }
/**\brief Return the ID of the region just clockwise (CW) of the fragment...
*
* ... when winding around the lower (\a fromLowerEnd is true) or
* upper (\a fromLowerEnd is false) endpoint of the fragment.
*/
RegionIdSet::value_type& cwRegion(bool fromLowerEnd) { return this->m_regionId[fromLowerEnd ? 0 : 1]; }
RegionIdSet::value_type cwRegion(bool fromLowerEnd) const { return this->m_regionId[fromLowerEnd ? 0 : 1]; }
/**\brief Return the next fragment bounding the region to the left of the fragment.
*
*/
FragmentId& nextFragment(bool forwardDir) { return this->m_next[forwardDir ? 1 : 0]; }
/// Mark a co-fragment as visited (or not).
void mark(bool orientation, int markVal)
{
this->m_marked[orientation ? 1 : 0] = markVal;
}
/// Return the markings on the forward (orientation true) or backward (false) co-fragment.
int marked(bool orientation) const
{
return this->m_marked[orientation ? 1 : 0];
}
/// Debug dump of fragment
void dump(RegionIdSet& ufind) const
{
......@@ -452,6 +489,8 @@ internal::HighPrecisionCoord cross2d(const internal::Coord oa[2], const internal
return result;
}
typedef std::vector<std::pair<smtk::model::Edge,bool> > OrientedEdges;
/**\brief Represent the neighborhood of a sweepline point, x.
*
* This holds a CCW-ordered list of edges incident to x, plus an
......@@ -956,6 +995,90 @@ struct Neighborhood
}
#endif // 0
}
void traverseLoop(OrientedEdges& result, std::set<RegionId>& neighborRegions, FragmentId fragId, bool orientation)
{
result.clear();
neighborRegions.clear();
FragmentId fragStart = fragId;
bool orientStart = orientation;
EdgeFragment* frag = &((*this->m_fragments)[fragId]);
RegionId lr = this->m_regionIds.find(frag->ccwRegion(orientStart));
std::cout << " ";
do
{
frag->mark(orientation, 1);
result.push_back(std::make_pair(frag->edge(), orientation ^ frag->orientation()));
neighborRegions.insert(this->m_regionIds.find(frag->ccwRegion(!orientation)));
fragId = frag->nextFragment(orientation);
std::cout << " " << fragId;
if (fragId == -1)
break;
frag = &((*this->m_fragments)[fragId]);
RegionId nextRegion = this->m_regionIds.find(frag->ccwRegion(false));
orientation = nextRegion == lr ? false : true;
std::cout << (orientation ? "+" : "-");
}
while (fragId != fragStart || orientation != orientStart);
std::cout << "\n";
}
void dumpLoop(OrientedEdges& loopEdges, std::set<RegionId>& neighborRegions)
{
std::cout << "Loop with neighbors ";
std::ostream_iterator<RegionId> out_reg(std::cout, " ");
std::copy (neighborRegions.begin(), neighborRegions.end(), out_reg);
std::cout << "\n";
for (OrientedEdges::const_iterator oe = loopEdges.begin(); oe != loopEdges.end(); ++oe)
{
if (oe->first.vertices().empty())
{
std::cout << " " << "periodic " << oe->first.name() << "\n";
}
else
{
model::Vertices endpts = oe->first.vertices();
double* a = endpts[endpts.size() == 1 ? 0 : (oe->second ? 0 : 1)].coordinates();
double* b = endpts[endpts.size() == 1 ? 0 : (oe->second ? 1 : 0)].coordinates();
std::cout << " " << a[0] << " " << a[1] << " -- " << b[0] << " " << b[1] << " " << oe->first.name() << "\n";
}
}
}
// Try generating output faces.
void dumpRegions2()
{
FragmentArray::const_iterator fit;
std::cout << "\nCreepy crawler\n";
fit = this->m_fragments->begin();
// The left/lower region of the first fragment to be inserted is always exterior
// to all faces. It corresponds to a "hole" cut in the infinite plane of all fragments.
RegionId outside = this->m_regionIds.find(fit->lowerRegion());
// Traverse every fragment. For each unprocessed coedge, if the region is equivalent
// to outside, queue the other coedge (if unprocessed) as an output face.
OrientedEdges loopEdges;
std::set<RegionId> neighborRegions;
FragmentId fid = 0;
for (fit = this->m_fragments->begin(); fit != this->m_fragments->end(); ++fit, ++fid)
{
std::cout << "Fragment " << fid << "-\n";
if (!fit->marked(false) && this->m_regionIds.find(fit->ccwRegion(false)) != outside)
{
this->traverseLoop(loopEdges, neighborRegions, fid, false);
this->dumpLoop(loopEdges, neighborRegions);
}
std::cout << "Fragment " << fid << "+\n";
if (!fit->marked(true) && this->m_regionIds.find(fit->ccwRegion(true)) != outside)
{
this->traverseLoop(loopEdges, neighborRegions, fid, true);
this->dumpLoop(loopEdges, neighborRegions);
}
std::cout << "\n";
}
}
};
#if 0
......@@ -1221,6 +1344,7 @@ smtk::model::OperatorResult CreateFaces::operateInternal()
neighborhood.dumpRegions();
neighborhood.mergeRelated();
neighborhood.dumpRegions();
neighborhood.dumpRegions2();
// Create vertex-use, chain, edge-use, loop, and face records
smtk::model::OperatorResult result;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment