|
cgma
|
#include <PartSurfFacetTool.hpp>
Definition at line 36 of file PartSurfFacetTool.hpp.
| PartSurfFacetTool::PartSurfFacetTool | ( | PartitionSurface * | surface | ) | [inline] |
Interface for initializing PartitionSurface facets
Definition at line 247 of file PartSurfFacetTool.hpp.
: mySurface(surface) {}
| CubitStatus PartSurfFacetTool::associate_points | ( | DLIList< CubitPoint * > & | facet_points, |
| DLIList< PartitionPoint * > & | geom_points | ||
| ) | [static, private] |
Definition at line 2057 of file PartSurfFacetTool.cpp.
{
int i;
DLIList<int> geom_indices(geom_points.size());
for (i = 0; i < geom_points.size(); i++ )
geom_indices.append(i);
for (i = facet_points.size(); i--; )
facet_points.step_and_get()->marked(-1);
geom_points.reset();
facet_points.reset();
while (geom_indices.size())
{
int index = geom_indices.pop();
PartitionPoint* geom_pt = geom_points.next(index);
const CubitVector pos(geom_pt->coordinates());
double shortest_dist_sqr = CUBIT_DBL_MAX;
int closest_index = -1;
for (i = 0; i < facet_points.size(); i++ )
{
CubitPoint* facet_pt = facet_points.next(i);
double dist_sqr = (pos - facet_pt->coordinates()).length_squared();
if (dist_sqr < shortest_dist_sqr)
{
if (facet_pt->marked() == -1)
{
shortest_dist_sqr = dist_sqr;
closest_index = i;
}
else
{
int j = facet_pt->marked();
CubitPoint* other_point = facet_points.next(j);
double other_dist_sqr = (pos - other_point->coordinates()).length_squared();
if (other_dist_sqr > dist_sqr)
{
shortest_dist_sqr = dist_sqr;
closest_index = i;
facet_pt->marked(-1);
geom_indices.append(j);
}
}
}
}
if (closest_index < 0)
{
assert(false);
for (i = facet_points.size(); i--; )
facet_points.step_and_get()->marked(0);
for (i = geom_points.size(); i--; )
geom_points.step_and_get()->mark = 0;
return CUBIT_FAILURE;
}
geom_pt->mark = closest_index;
facet_points.next(closest_index)->marked(index);
}
for (i = facet_points.size(); i--; )
facet_points.step_and_get()->marked(0);
facet_points.reset();
for (i = geom_points.size(); i--; )
{
PartitionPoint* geom_pt = geom_points.step_and_get();
CubitPoint* facet_pt = facet_points.next(geom_pt->mark);
geom_pt->mark = 0;
assert(!TDVGFacetOwner::get(facet_pt));
facet_pt->set(geom_pt->coordinates());
CubitPointData* point_data = dynamic_cast<CubitPointData*>(facet_pt);
assert(!!point_data);
if (geom_pt->facet_point())
geom_pt->facet_point()->merge_points( point_data );
else
geom_pt->facet_point(point_data);
}
return CUBIT_SUCCESS;
}
| CubitFacet * PartSurfFacetTool::closest_facet | ( | const CubitVector & | input_position, |
| const DLIList< CubitFacetData * > & | facets, | ||
| CubitVector & | result_position | ||
| ) | [static] |
Definition at line 1917 of file PartSurfFacetTool.cpp.
{
CubitFacet* return_val = 0;
double closest_dist_sqr = CUBIT_DBL_MAX;
CubitVector facet_position;
const int size = facet_list.size();
for ( int i = 0; i < size; i++ ) {
CubitFacet* facet = facet_list.next(i);
closest_pt_on_facet( facet, input_position, facet_position );
double dist_sqr = (input_position - facet_position).length_squared();
if ( dist_sqr < closest_dist_sqr ) {
closest_dist_sqr = dist_sqr;
result_position = facet_position;
return_val = facet;
}
}
return return_val;
}
| void PartSurfFacetTool::closest_pt_on_facet | ( | CubitFacet * | facet, |
| const CubitVector & | input_position, | ||
| CubitVector & | result_position | ||
| ) | [static, private] |
Helper functions for init_facet_data
Definition at line 324 of file PartSurfFacetTool.cpp.
{
// Get triangle vertices
CubitVector p0(facet->point(0)->coordinates());
CubitVector p1(facet->point(1)->coordinates());
CubitVector p2(facet->point(2)->coordinates());
/*
Algorithm from:
"Distance Between Point and Triangle in 3D"
David Eberly
Magic Software, Inc.
Sept. 28, 1999
Use barycentric coordinates. Coordinates are
calculated in the range [0,det] rather than [0,1]
to avoid the fp division entirely where it can
be avoided.
^v*t
\R2|
\ |
\|
*p2
|\
| \ R1
R3 | \
| \
| R0 \
| \p1
---*------*--->u*s
|p0 \ R6
R4 | R5 \
| \u+v=det
*/
CubitVector s(p1 - p0); // the u (or s) axis in parameterized space
CubitVector t(p2 - p0); // the v (or t) axis in parameterized space
CubitVector d(p0 - p); // vector from input position to corner at (u,v) = (0,0)
// Pre-calculate all the dot products we need
// Name the dot product of vectors 'a' and 'b' as 'ab'
double ss = s.length_squared();
double st = s % t;
double tt = t.length_squared();
double sd = s % d;
double td = t % d;
// Calculate barycentric coordinates in the range [0,det]
double det = ss*tt - st*st;
double u = st*td - tt*sd;
double v = st*sd - ss*td;
// Big tree of conditionals to determine which of the
// regions in the above diagram the projection of
// the point into the plane lies in.
if ( u+v < det )
{
if ( u < 0 )
{
if( v < 0 ) // Region 4
{
if ( sd < 0 )
{
if ( -sd > ss )
result = p1;
else
result = p0 + (-sd/ss) * s;
}
else if ( td < 0 )
{
if ( -td > tt )
result = p2;
else
result = p0 + (-td/tt) * t;
}
else
{
result = p0;
}
}
else // Region 3 (Edge p2-p0, u->0)
{
if ( td > 0 )
result = p0;
else if ( -td > tt )
result = p2;
else
result = p0 + (-td/tt) * t;
}
}
else if ( v < 0) // Region 5 (Edge p0-p1, v->0)
{
if ( sd > 0 )
result = p0;
else if ( -sd > ss )
result = p1;
else
result = p0 + (-sd/ss) * s;
}
else // Region 0 (Interior)
{
result = p0 + (1.0/det) * (u*s + v*t);
}
}
else if ( u < 0 ) // Region 2
{
double num = tt + td - st - sd;
if ( num > 0.0 )
{
double den = ss - 2*st + tt;
if ( num >= den ) // (Point p1)
result = p1;
else // (Edge p1-p2)
{
u = num / den;
result = p0 + u*s + (1-u)*t;
}
}
else if ( td >= 0 ) // (Point p0)
result = p0;
else if ( tt+td <= 0 ) // (Point p2)
result = p2;
else // (Edge p2-p0)
result = p0 + (-td/tt)*t;
}
else if ( v < 0 ) // Region 6
{
double num = tt + td - st - sd;
double den = ss - 2*st + tt;
if (num < den)
{
if ( num < 0 ) // (Point p1)
result = p2;
else // (Edge p1-p2)
{
u = num / den;
result = p0 + u*s + (1-u)*t;
}
}
else if ( sd >= 0 ) // (Point p0)
result = p0;
else if ( ss+sd <= 0 ) // (Point p1)
result = p1;
else // (Edge p0-p1)
result = p0 + (-sd/ss)*s;
}
else // Region 1 (Edge p1-p2, u+v->1)
{
double num = tt + td - st - sd;
if ( num <= 0 )
result = p2;
else
{
double den = ss - 2*st + tt;
if ( num >= den )
result = p1;
else
{
u = num/den;
result = p0 + u*s + (1-u)*t;
}
}
}
}
| CubitStatus PartSurfFacetTool::collapse_edge | ( | CubitPoint * | keep_point, |
| CubitPoint * | dead_point, | ||
| DLIList< CubitFacetData * > * | unowned = 0 |
||
| ) | [static] |
Definition at line 1046 of file PartSurfFacetTool.cpp.
{
int i;
CubitPointData* keep_pt = dynamic_cast<CubitPointData*>(keep);
CubitPointData* dead_pt = dynamic_cast<CubitPointData*>(dead);
CubitFacetEdge* dead_edge;
assert(keep_pt&&dead_pt);
// Cannot proceed if dead_pt is owned by a PartitionPoint.
if ( TDVGFacetOwner::get(dead_pt) )
return CUBIT_FAILURE;
// Get list of facets to be destroyed when edge is collapsed
DLIList<CubitFacet*> dead_facets;
keep->shared_facets(dead_pt,dead_facets);
DLIList<PartitionSurface*> dead_facet_owners(dead_facets.size());
DLIList<CubitFacetData*> dead_facet_ds(dead_facets.size());
CAST_LIST(dead_facets, dead_facet_ds, CubitFacetData);
// Find other edges to be destroyed when edge is collapsed.
// cannot proceed if any of them belong to a PartitionCurve.
// Also, find owners of each facet to be destroyed.
dead_facets.reset();
for ( i = dead_facets.size(); i--; )
{
CubitFacet* facet = dead_facets.get_and_step();
int keep_index = facet->point_index(keep);
int dead_index = facet->point_index(dead);
int othr_index = (keep_index + 1) % 3;
if ( othr_index == dead_index )
othr_index = (keep_index + 2) % 3;
assert( keep_index >= 0 && dead_index >= 0 );
dead_edge = dead_pt->shared_edge(facet->point(othr_index));
if ( TDVGFacetOwner::get(dead_edge) )
return CUBIT_FAILURE;
PartitionSurface* surf = dynamic_cast<PartitionSurface*>(TDVGFacetOwner::get(facet));
dead_facet_owners.append( surf );
}
PRINT_INFO("Collapsing edge (%f,%f,%f)->(%f,%f,%f) (%f)\n",
keep_pt->coordinates().x(), keep_pt->coordinates().y(), keep_pt->coordinates().z(),
dead_pt->coordinates().x(), dead_pt->coordinates().y(), dead_pt->coordinates().z(),
(keep_pt->coordinates()-dead_pt->coordinates()).length());
// Get PartitionCurve to update for collapsed edge.
PartitionCurve* dead_edge_owner = 0;
dead_edge = dead_pt->shared_edge(keep_pt);
if (dead_edge)
dead_edge_owner = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(dead_edge));
// Collapse the edge
if ( !keep_pt->collapse_edge(dead_pt) )
return CUBIT_FAILURE;
// Update owning curve
if (dead_edge_owner)
dead_edge_owner->remove_dead_facet( (CubitFacetEdgeData*)dead_edge );
// Update facet owners for dead facets.
dead_facet_ds.reset();
dead_facet_owners.reset();
for ( i = dead_facet_ds.size(); i--; )
{
CubitFacetData* facet = dead_facet_ds.get_and_step();
PartitionSurface* facet_owner = dead_facet_owners.get_and_step();
if (!facet_owner)
unowned->append(facet);
else
facet_owner->notify_destroyed(facet);
}
return CUBIT_SUCCESS;
}
| void PartSurfFacetTool::edge_facets | ( | CubitFacetEdge * | edge, |
| const DLIList< CubitFacet * > & | input_facets, | ||
| DLIList< CubitFacet * > & | output_list | ||
| ) | [static, private] |
Definition at line 2275 of file PartSurfFacetTool.cpp.
{
edge->facets(output_facets);
output_facets.intersect( input_facets );
}
| void PartSurfFacetTool::edge_facets | ( | PartitionSurface * | surface, |
| CubitFacetEdge * | edge, | ||
| DLIList< CubitFacet * > & | facets | ||
| ) | [static, private] |
Definition at line 2251 of file PartSurfFacetTool.cpp.
{
edge->facets(facets);
for (int i = facets.size(); i--; )
if (TDVGFacetOwner::get(facets.step_and_get()) != surf)
facets.change_to(0);
facets.remove_all_with_value(0);
}
| CubitStatus PartSurfFacetTool::fix_move_point | ( | CubitPoint * | point, |
| const CubitVector & | new_pos, | ||
| const DLIList< CubitFacetData * > & | facets, | ||
| DLIList< CubitFacetData * > & | old_facets, | ||
| DLIList< CubitFacetData * > & | new_facets, | ||
| PartitionSurface * | owning_surf = 0 |
||
| ) | [static] |
Definition at line 1693 of file PartSurfFacetTool.cpp.
{
int i;
DLIList<CubitFacet*> facets(facetds.size());
for (i = 0; i < facetds.size(); i++)
facets.append(facetds.next(i));
// Look for a triangle containing the passed point.
CubitVector closest_pos, vect;
CubitFacet* facet = closest_facet(new_pos, facetds, closest_pos );
if ( facet == NULL)
return CUBIT_FAILURE;
if (facet->point_index(point) >= 0)
{
dynamic_cast<CubitPointData*>(point)->set(new_pos);
return CUBIT_SUCCESS;
}
PRINT_WARNING("Refacetting surface near (%f,%f,%f)\n",
new_pos.x(), new_pos.y(), new_pos.z());
// Line direction
const CubitVector dir(point->coordinates() - new_pos);
if (DEBUG_FLAG(145))
{
GfxDebug::draw_facet(facet, CUBIT_BLUE_INDEX);
GfxDebug::draw_point(point->coordinates(), CUBIT_BLUE_INDEX);
GfxDebug::draw_point(new_pos, CUBIT_CYAN_INDEX);
GfxDebug::draw_line(point->coordinates(), new_pos, CUBIT_BLUE_INDEX);
GfxDebug::flush();
}
// Find where line exits first triangle
CubitFacetEdge* edge = 0;
bool leftofpoint[3];
for ( i = 0; i < 3; i++)
{
CubitVector vect = facet->point(i)->coordinates() - new_pos;
vect *= dir;
leftofpoint[i] = (vect % facet->normal()) >= 0.0;
}
for ( i = 0; i < 3; ++i)
if (leftofpoint[i] && !leftofpoint[(i+1)%3])
{
edge = facet->edge((i+2)%3);
break;
}
if (!edge)
return CUBIT_FAILURE;
// Find the set of triangles the line from the old
// position to the new position crosses.
DLIList<CubitFacet*> intersect_list, edge_facets;
while (facet->point_index(point) < 0)
{
intersect_list.append(facet);
if (DEBUG_FLAG(145))
{
GfxDebug::draw_facet_edge(edge, CUBIT_WHITE_INDEX);
GfxDebug::draw_facet(facet, CUBIT_BLUE_INDEX);
GfxDebug::flush();
}
// Find the facet on the other side of the edge
edge_facets.clean_out();
if (surface)
PartSurfFacetTool::edge_facets(surface, edge, edge_facets);
else
PartSurfFacetTool::edge_facets( edge, facets, edge_facets );
edge_facets.move_to(facet);
assert(edge_facets.get() == facet);
if(edge_facets.size() != 2)
break;
facet = edge_facets.step_and_get();
// Find the edge that the line intersects exiting the facet
i = facet->edge_index(edge);
vect = facet->point(i)->coordinates() - new_pos;
vect *= dir;
if (vect % facet->normal() >= 0.0)
edge = facet->edge((i+1)%3);
else
edge = facet->edge((i+2)%3);
}
if (facet)
{
if (DEBUG_FLAG(145))
{
GfxDebug::draw_facet_edge(edge, CUBIT_WHITE_INDEX);
GfxDebug::flush();
}
intersect_list.append_unique(facet);
}
// Get ordered boundary
DLIList<CubitPoint*> boundary_list;
DLIList<CubitFacetEdge*> point_edges;
CubitFacetEdge* prev_edge = 0;
CubitFacet* prev_facet = 0;
// Find one boundary edge to start with
for (i = intersect_list.size(); !prev_edge && i--; )
{
CubitFacet* facet = intersect_list.get_and_step();
for (int j = 0; j < 3; j++)
{
CubitFacetEdge* edge = facet->edge(j);
edge_facets.clean_out();
if (surface)
PartSurfFacetTool::edge_facets( surface, edge, edge_facets);
else
PartSurfFacetTool::edge_facets( edge, facets, edge_facets );
edge_facets.intersect(intersect_list);
if (edge_facets.size() == 1)
{
prev_edge = edge;
prev_facet = facet;
break;
}
}
}
CubitFacetEdge* first_edge = prev_edge;
// Traverse boundary edges in order
do
{
int direction = prev_facet->edge_use( prev_facet->edge_index(prev_edge) );
CubitPoint* pt = prev_edge->point( direction == -1 ? 0 : 1 );
point_edges.clean_out();
pt->edges( point_edges );
if (DEBUG_FLAG(145))
{
GfxDebug::draw_facet_edge( prev_edge, CUBIT_LIGHTBLUE_INDEX );
GfxDebug::flush();
}
boundary_list.append(pt);
point_edges.move_to(prev_edge);
assert(point_edges.get() == prev_edge);
point_edges.extract();
prev_edge = 0;
while (point_edges.size())
{
CubitFacetEdge* edge = point_edges.pop();
edge_facets.clean_out();
if (surface)
PartSurfFacetTool::edge_facets( surface, edge, edge_facets);
else
PartSurfFacetTool::edge_facets( edge, facets, edge_facets );
edge_facets.intersect(intersect_list);
if (edge_facets.size() == 1)
{
if (prev_edge) {
prev_edge = 0;
break;
}
prev_edge = edge;
prev_facet = edge_facets.get();
}
}
if (!prev_edge)
{
PRINT_ERROR("Problems finding boundary to re-facet around split point.\n");
return CUBIT_FAILURE;
}
} while (prev_edge != first_edge);
// Construct new facets in affected region by connecting
// the split point to each boundary point
int junk = 0;
//DLIList<CubitFacetData*> new_facets, old_facets(intersect_list.size());
if (!boundary_list.move_to(point))
{
PRINT_ERROR("Problems finding region around split point for re-facetting.\n");
return CUBIT_FAILURE;
}
boundary_list.step();
CubitPoint* prev_pt = boundary_list.get_and_step();
for (i = boundary_list.size(); i > 2; i--)
{
CubitPoint* next_pt = boundary_list.get_and_step();
CubitFacetData* new_facet = new CubitFacetData( point, prev_pt, next_pt, &junk);
new_facets.append(new_facet);
prev_pt = next_pt;
if (DEBUG_FLAG(145))
{
GfxDebug::draw_facet( new_facet, CUBIT_YELLOW_INDEX );
GfxDebug::flush();
}
}
CAST_LIST( intersect_list, old_facets, CubitFacetData );
assert(intersect_list.size() == old_facets.size());
dynamic_cast<CubitPointData*>(point)->set(new_pos);
//replace_facets( old_facets, new_facets );
return CUBIT_SUCCESS;
}
| CubitStatus PartSurfFacetTool::get_boundary_chain | ( | CubitPoint * | start_point, |
| CubitFacetEdge * | start_edge, | ||
| CubitPoint * | end_point, | ||
| DLIList< CubitFacetEdge * > & | result | ||
| ) | [private] |
Definition at line 846 of file PartSurfFacetTool.cpp.
{
DLIList<CubitFacetEdge*> point_edges;
//assert(start_edge->marked());
assert(result_list.size() == 0);
CubitPoint* point = start_point;
CubitFacetEdge* edge = start_edge;
while (true)
{
result_list.append(edge);
point = edge->other_point(point);
if (TDVGFacetOwner::get(point))
return point == end_point ? CUBIT_SUCCESS : CUBIT_FAILURE;
point->edges(point_edges);
for (int i = point_edges.size(); i--; )
{
CubitFacetEdge* point_edge = point_edges.step_and_get();
//if (point_edge->marked() != 1 || point_edge == edge)
if (boundary_set.count(point_edge) == 0 || point_edge == edge)
point_edges.change_to(0);
}
point_edges.remove_all_with_value(0);
if (point_edges.size() != 1)
return CUBIT_FAILURE;
edge = point_edges.remove();
}
// unreachable
return CUBIT_SUCCESS;
}
| CubitStatus PartSurfFacetTool::get_facet_points_and_edges | ( | const DLIList< CubitFacetData * > & | facets, |
| DLIList< CubitPoint * > & | boundary_points, | ||
| DLIList< CubitPoint * > & | interior_points, | ||
| DLIList< CubitFacetEdge * > & | boundary_edges, | ||
| DLIList< CubitFacetEdge * > & | interior_edges | ||
| ) | [static] |
Definition at line 2157 of file PartSurfFacetTool.cpp.
{
int i, j;
CubitStatus result = CUBIT_SUCCESS;
CubitFacetData* facet;
DLIList<CubitFacetEdge*> edge_list;
const int count = facets.size();
// Initialize marks
for (i = 0; i < count; i++ )
{
facet = facets.next(i);
for (j = 0; j < 3; j++)
{
facet->edge(j)->marked(0);
facet->point(j)->marked(1);
}
}
// Mark each edge with a count of the number of
// adjcent facets.
for (i = 0; i < count; i++ )
{
facet = facets.next(i);
for (j = 0; j < 3; j++)
facet->edge(j)->marked(facet->edge(j)->marked() + 1);
}
// Collect points and clear point marks
for (i = 0; i < count; i++ )
{
facet = facets.next(i);
for (j = 0; j < 3; j++)
{
CubitPoint* point = facet->point(j);
if (!point->marked())
continue;
point->marked(0);
point->edges(edge_list);
bool boundary = false;
while (edge_list.size())
if (edge_list.pop()->marked() == 1)
boundary = true;
if (boundary)
boundary_points.append(point);
else
interior_points.append(point);
}
}
// Collect edges and clear edge marks
for (i = 0; i < count; i++ )
{
facet = facets.next(i);
for (j = 0; j < 3; j++)
{
CubitFacetEdge* edge = facet->edge(j);
switch (edge->marked())
{
case 0:
continue;
case 1:
boundary_edges.append(edge);
break;
case 2:
interior_edges.append(edge);
break;
default:
result = CUBIT_FAILURE;
assert(false);
}
edge->marked(0);
}
}
return result;
}
| Curve * PartSurfFacetTool::get_real_curve | ( | DLIList< PartitionCurve * > & | curve_list, |
| PartitionPoint *& | start_point, | ||
| PartitionPoint *& | end_point | ||
| ) | [static, private] |
Definition at line 810 of file PartSurfFacetTool.cpp.
{
SubEntitySet* set = &(curve_list.get()->sub_entity_set());
DLIList<PartitionEntity*> tmp_set(curve_list.size());
set->get_sub_entities(tmp_set);
if (tmp_set.size() != curve_list.size())
return 0;
tmp_set.reset();
curve_list.reset();
if (tmp_set.get() != curve_list.get())
{
curve_list.reverse();
curve_list.reset();
}
for (int i = curve_list.size(); i--; )
if (curve_list.get_and_step() != tmp_set.get_and_step())
return 0;
// Get real curve
Curve* real_curve = dynamic_cast<Curve*>(set->get_entity());
assert(!!real_curve);
DLIList<TopologyBridge*> point_bridges(2);
real_curve->get_children(point_bridges, false, set->get_owner_layer());
point_bridges.reset();
start_point = dynamic_cast<PartitionPoint*>(point_bridges.get());
end_point = dynamic_cast<PartitionPoint*>(point_bridges.next());
assert(start_point && end_point);
return real_curve;
}
| CubitStatus PartSurfFacetTool::init_facet_data | ( | DLIList< CubitFacetData * > & | facets | ) |
Definition at line 550 of file PartSurfFacetTool.cpp.
{
assert(!mySurface->has_facets());
int i;
CubitStatus rval;
DLIList<CubitPoint*> boundary_points, interior_points;
DLIList<CubitFacetEdge*> boundary_edges, interior_edges;
DLIList<PartitionPoint*> geom_points, interior_geom_points;
// Get facet data
rval = get_facet_points_and_edges( facets, boundary_points,
interior_points, boundary_edges, interior_edges );
if (!rval)
{
PRINT_ERROR("Internal error at %s:%d\n", __FILE__, __LINE__ );
return CUBIT_FAILURE;
}
// Get real points on surface boundary
mySurface->get_points(geom_points);
for (i = 0; i < geom_points.size(); i++ )
{
if (!geom_points[i]->real_point())
geom_points[i] = 0;
// also process for hardpoints
if (geom_points[i])
{
PartitionCurve* curve = geom_points[i]->next_curve();
if ( curve->measure() < GEOMETRY_RESABS &&
curve->start_point() == curve->end_point() )
{
geom_points[i] = 0;
}
}
}
geom_points.remove_all_with_value(0);
// Group geometric points into boundary and interior sets
for (i = geom_points.size(); i--; )
{
PartitionPoint* point = geom_points.step_and_get();
bool boundary = false;
PartitionCurve* curve = 0;
while ( (curve = point->next_curve(curve)) )
if (curve->is_in_surface(mySurface,true))
boundary = true;
if (!boundary)
{
geom_points.change_to(0);
interior_geom_points.append(point);
}
}
geom_points.remove_all_with_value(0);
// Associate each boundary geometry point with the closest
// boundary facet point.
if(boundary_points.size() == 0 && geom_points.size() != 0)
rval = CUBIT_FAILURE;
else
rval = associate_points( boundary_points, geom_points );
if (!rval)
return CUBIT_FAILURE;
// Associate each interior geometry point with the closest
// interior facet point.
rval = associate_points( interior_points, interior_geom_points );
if (!rval)
return CUBIT_FAILURE;
if (DEBUG_FLAG(145))
{
draw_edges( boundary_edges, CUBIT_ORANGE_INDEX, true, false, CUBIT_WHITE_INDEX, true );
draw_edges( interior_edges, CUBIT_WHITE_INDEX );
}
// Populate sets
boundary_set.clear();
interior_set.clear();
for (i = boundary_edges.size(); i--; )
boundary_set.insert(boundary_edges.step_and_get());
for (i = interior_edges.size(); i--; )
interior_set.insert(interior_edges.step_and_get());
// For each loop on the surface...
PartitionLoop* loop = 0;
DLIList<PartitionCurve*> curve_set;
DLIList<CubitFacetEdge*> point_edges, edge_set_1, edge_set_2;
DLIList<PartitionCurve*> nonmanifold_stack;
while ( (loop = mySurface->next_loop(loop)) )
{
// Find coedge beginning at real vertex (must be at least one)
PartitionCoEdge* coedge = loop->first_coedge();
while (!coedge->start_point()->real_point())
{
coedge = coedge->next();
assert(coedge != loop->first_coedge());
}
PartitionCoEdge* first_coedge = coedge; // so we know when to stop
do // Loop until all curves in loop have been handled (back to first_coedge)
{
// Keep track of start and end
PartitionCurve* first_curve = coedge->get_curve();
PartitionPoint* start_point = coedge->start_point();
PartitionPoint* end_point = coedge->end_point();
// Hardpoints (meeting all cases below) are a special
// case loop that should not be handled in the partitioning.
if (loop->num_coedges() == 1 &&
first_curve->measure() < GEOMETRY_RESABS &&
start_point == end_point)
break;
// Get list of curves until next real vertex
curve_set.clean_out();
curve_set.append(first_curve);
while (!coedge->end_point()->real_point())
{
coedge = coedge->next();
curve_set.append(coedge->get_curve());
end_point = coedge->end_point();
assert(&first_curve->sub_entity_set() == &coedge->get_curve()->sub_entity_set());
}
if (DEBUG_FLAG(145))
{
curve_set.reset();
for (i = curve_set.size(); i--; )
{
GMem gmem;
PartitionCurve* c = curve_set.get_and_step();
c->get_geometry_query_engine()->get_graphics( c, &gmem );
GfxDebug::draw_polyline(gmem.point_list(), gmem.pointListCount, CUBIT_RED_INDEX );
}
GfxDebug::flush();
}
// Special case for non-manifold curves
if (first_curve->is_nonmanifold(mySurface))
{
// Don't do the same non-manifold curve twice
curve_set.reset();
nonmanifold_stack.last();
if (nonmanifold_stack.size() &&
curve_set.get() == nonmanifold_stack.get())
{
for (i = curve_set.size(); i--; )
{
PartitionCurve* curv1 = curve_set.get_and_step();
PartitionCurve* curv2 = nonmanifold_stack.pop();
assert(curv1 == curv2);
if (curv1 != curv2) {
PRINT_ERROR("Internal error at %s:%d\n", __FILE__, __LINE__);
return CUBIT_FAILURE;
}
}
}
else
{
for (i = curve_set.size(); i--; )
nonmanifold_stack.append(curve_set.get_and_step());
if (!seam_nonmanifold_curves(curve_set, facets))
{
return CUBIT_FAILURE;
}
}
coedge = coedge->next();
if (coedge != first_coedge)
continue;
else
break;
}
// Get facet edges adjacent to first point
point_edges.clean_out();
start_point->facet_point()->edges(point_edges);
// For each boundary edge on the point, look for a chain
// of connected boundary edges.
edge_set_1.clean_out();
edge_set_2.clean_out();
while(point_edges.size())
{
CubitFacetEdge* edge = point_edges.pop();
if (boundary_set.count(edge) == 0) // skip non-boundary edges
continue;
edge_set_2.clean_out();
if (!get_boundary_chain(start_point->facet_point(), edge,
end_point->facet_point(), edge_set_2))
continue; // skip edges that don't begin a chain that reaches the end vertex
// If only one chain found so far, store the chain and
// continue to the next edge around the point
if (!edge_set_1.size())
{
edge_set_1 = edge_set_2;
edge_set_2.clean_out();
continue;
}
// If we reached this point, handle special case where
// loop is composed of two real curves and we need a
// geometric check to determine which half of the facet edge
// loop goes with which curve.
edge_set_1.reset();
edge_set_2.reset();
CubitVector set_1_mid = edge_set_1.get()->center();
CubitVector set_2_mid = edge_set_2.get()->center();
CubitVector set_1_closest, set_2_closest;
first_curve->closest_point_trimmed(set_1_mid, set_1_closest);
first_curve->closest_point_trimmed(set_2_mid, set_2_closest);
set_1_closest -= set_1_mid;
set_2_closest -= set_2_mid;
if (set_2_closest.length_squared() < set_1_closest.length_squared())
edge_set_1 = edge_set_2;
} // while(point_edges.size())
// We have the chain of edges to associate with the curve
// set. Seam with adjacent surface facettings (if any)
if (DEBUG_FLAG(145))
draw_edges( edge_set_1, CUBIT_RED_INDEX, true );
if (!seam_curves( curve_set, edge_set_1, facets ))
return CUBIT_FAILURE;
coedge = coedge->next();
} while (coedge != first_coedge);
} // while (loop)
// attach facets to surface
mySurface->set_facet_data(facets);
return CUBIT_SUCCESS;
}
| CubitStatus PartSurfFacetTool::seam_curve | ( | DLIList< CubitFacetEdgeData * > & | new_edge_list, |
| PartitionCurve * | curve, | ||
| DLIList< CubitFacetData * > & | adjacent_facets, | ||
| DLIList< CubitFacetEdgeData * > * | dead_edge_ptrs = 0 |
||
| ) | [static] |
Definition at line 1387 of file PartSurfFacetTool.cpp.
{
DLIList<CubitFacetData*> old_facets, new_facets;
const double FRACT_TOL = 0.1;
int curve_color = CUBIT_GREEN_INDEX;
if (DEBUG_FLAG(145))
{
RefEntity* ent = dynamic_cast<RefEntity*>(curve->topology_entity());
while (ent && ent->color() < 0)
{
DLIList<RefEntity*> list;
ent->get_parent_ref_entities(list);
list.reset();
if (!list.size()) break;
ent = list.get();
}
if (ent)
curve_color = ent->color();
}
// Vertices should already be "seamed". Verify...
PartitionPoint* start_vtx = curve->start_point();
PartitionPoint* end_vtx = curve->end_point();
CubitPointData* start_point = start_vtx->facet_point();
CubitPointData* end_point = end_vtx->facet_point();
edge_list.last();
CubitFacetEdgeData* last_edge = edge_list.get();
edge_list.reset();
CubitFacetEdgeData* first_edge = edge_list.get();
if (!first_edge->other_point(start_point) ||
!last_edge->other_point(end_point))
{
PRINT_ERROR("Internal error at %s:%d\n", __FILE__, __LINE__);
assert(0);
return CUBIT_FAILURE;
}
// Get direction of parameter (probably always increasing...)
double period;
const bool fwdparam = curve->is_periodic(period) ? period > 0.0 :
curve->start_param() < curve->end_param();
// Get list of facet edges on curve.
DLIList<CubitFacetEdgeData*> curve_edges;
curve->get_facet_data(curve_edges);
if (!curve_edges.size())
{
curve->set_facet_data( edge_list );
return CUBIT_SUCCESS;
}
// Seam edge lists
double curve_param = curve->start_param();
double new_param = curve->start_param();
curve_edges.reset();
edge_list.reset();
CubitFacetEdgeData* curve_edge = curve_edges.get_and_step();
CubitFacetEdgeData* new_edge = edge_list.get_and_step();
CubitPoint* prev_point = start_point;
double orig_crv_len = curve_edge->length();
double orig_new_len = new_edge->length();
double split_tol = FRACT_TOL * CUBIT_MIN(orig_crv_len, orig_new_len);
while (curve_edge || new_edge)
{
if (!curve_edge || !new_edge)
{
PRINT_ERROR("Internal error at %s:%d\n", __FILE__, __LINE__ );
assert(0);
return CUBIT_FAILURE;
}
CubitPoint* curve_point = curve_edge->other_point(prev_point);
CubitPoint* new_point = new_edge->other_point(prev_point);
if (DEBUG_FLAG(145)) {
GfxDebug::draw_point(curve_point->coordinates(), curve_color);
GfxDebug::draw_facet_edge(curve_edge, curve_color);
GfxDebug::draw_point(new_point->coordinates(), curve_color + 1);
GfxDebug::draw_facet_edge(new_edge, curve_color + 1);
GfxDebug::flush();
}
double prev_curve_param = curve_param;
double prev_new_param = new_param;
curve_param = curve->u_from_position(curve_point->coordinates());
new_param = curve->u_from_position(new_point->coordinates());
if (curve->is_periodic(period))
{
if ((prev_curve_param > curve_param) == fwdparam)
curve_param += period;
if ((prev_new_param > new_param) == fwdparam)
new_param += period;
}
if ((curve_param > new_param) == fwdparam)
{
CubitFacetEdgeData* split_edge = 0;
CubitVector edge_pos;
curve_edge->closest_point( new_point->coordinates(), edge_pos );
CubitPoint* split = split_edge_closest( curve_edge,
edge_pos,
split_tol,
split_edge,
facets );
if(!split)
return CUBIT_FAILURE;
if (split == prev_point)
{
// new_edge is very small compared to split_edge
assert(!split_edge);
old_facets.clean_out();
if (!collapse_edge(prev_point, new_point, &old_facets))
{
if (!collapse_edge(new_point, prev_point, &old_facets))
{
return CUBIT_FAILURE;
}
std::swap(prev_point, new_point);
}
if (dead_ptrs)
dead_ptrs->append( new_edge );
facets -= old_facets;
if (edge_list.is_at_beginning())
new_edge = 0;
else
{
new_edge = edge_list.get_and_step();
orig_new_len = new_edge->length();
split_tol = FRACT_TOL * CUBIT_MIN(orig_crv_len, orig_new_len);
}
continue;
}
if (split_edge)
{
if (curve_edge->other_point(prev_point))
std::swap(split_edge, curve_edge);
}
else
{
assert(split == curve_point);
split_edge = curve_edge;
if (curve_edges.is_at_beginning())
curve_edge = 0;
else
{
curve_edge = curve_edges.get_and_step();
orig_crv_len = curve_edge->length();
split_tol = FRACT_TOL * CUBIT_MIN(orig_crv_len, orig_new_len);
}
}
// Move split point to position of other point (safely)
#ifdef PART_SURF_REFACET
double d_sqr = (edge_pos - new_point->coordinates()).length_squared();
bool close = d_sqr < (GEOMETRY_RESABS*GEOMETRY_RESABS);
old_facets.clean_out();
new_facets.clean_out();
if (close)
dynamic_cast<CubitPointData*>(split)->set(new_point->coordinates());
else if (!fix_move_point( split, new_point->coordinates(), facets, old_facets, new_facets ))
return CUBIT_FAILURE;
facets -= old_facets;
facets += new_facets;
#else
dynamic_cast<CubitPointData*>(split)->set(new_point->coordinates());
#endif
CubitStatus s1 = split->merge_points(new_point);
CubitStatus s2 = split_edge->merge_edges(new_edge);
if (dead_ptrs)
dead_ptrs->append(new_edge);
assert(s1 && s2);
prev_point = split;
if (edge_list.is_at_beginning())
new_edge = 0;
else
{
new_edge = edge_list.get_and_step();
orig_new_len = new_edge->length();
split_tol = FRACT_TOL * CUBIT_MIN(orig_crv_len, orig_new_len);
}
}
else
{
CubitFacetEdgeData* split_edge = 0;
CubitVector edge_pos;
new_edge->closest_point( curve_point->coordinates(), edge_pos );
CubitPoint* split = split_edge_closest( new_edge,
edge_pos,
split_tol,
split_edge,
facets );
if(!split)
return CUBIT_FAILURE;
if (split == prev_point)
{
// curve_edge is very small compared to split_edge
assert(!split_edge);
old_facets.clean_out();
if (!collapse_edge(prev_point,curve_point,&old_facets))
{
if (!collapse_edge(curve_point, prev_point, &old_facets))
{
return CUBIT_FAILURE;
}
std::swap(curve_point, prev_point);
}
facets -= old_facets;
if (dead_ptrs)
dead_ptrs->append(curve_edge);
if (curve_edges.is_at_beginning())
curve_edge = 0;
else
{
curve_edge = curve_edges.get_and_step();
orig_crv_len = curve_edge->length();
split_tol = FRACT_TOL * CUBIT_MIN(orig_crv_len, orig_new_len);
}
continue;
}
if (split_edge)
{
if (new_edge->other_point(prev_point))
std::swap(split_edge, new_edge);
}
else
{
assert(split == new_point);
split_edge = new_edge;
if (edge_list.is_at_beginning())
new_edge = 0;
else
{
new_edge = edge_list.get_and_step();
orig_new_len = new_edge->length();
split_tol = FRACT_TOL * CUBIT_MIN(orig_crv_len, orig_new_len);
}
}
// Move split point to position of other point (safely)
#ifdef PART_SURF_REFACET
double d_sqr = (edge_pos - curve_point->coordinates()).length_squared();
bool close = d_sqr < (GEOMETRY_RESABS*GEOMETRY_RESABS);
old_facets.clean_out();
new_facets.clean_out();
if (close)
dynamic_cast<CubitPointData*>(split)->set(curve_point->coordinates());
else if (!fix_move_point( split, curve_point->coordinates(), facets, old_facets, new_facets ))
return CUBIT_FAILURE;
facets -= old_facets;
facets += new_facets;
#else
dynamic_cast<CubitPointData*>(split)->set(curve_point->coordinates());
#endif
CubitStatus s2, s1 = CUBIT_SUCCESS;
if (curve_point != split)
s1 = curve_point->merge_points(split);
s2 = curve_edge->merge_edges(split_edge);
assert(s1 && s2);
if (CUBIT_SUCCESS != s1 || CUBIT_SUCCESS != s2) {
PRINT_ERROR("Internal error at %s:%d\n", __FILE__, __LINE__);
return CUBIT_FAILURE;
}
if (dead_ptrs)
dead_ptrs->append(split_edge);
prev_point = curve_point;
if (curve_edges.is_at_beginning())
curve_edge = 0;
else
{
curve_edge = curve_edges.get_and_step();
orig_crv_len = curve_edge->length();
split_tol = FRACT_TOL * CUBIT_MIN(orig_crv_len, orig_new_len);
}
}
}
return CUBIT_SUCCESS;
}
| CubitStatus PartSurfFacetTool::seam_curves | ( | DLIList< PartitionCurve * > & | curve_list, |
| DLIList< CubitFacetEdge * > & | edge_list, | ||
| DLIList< CubitFacetData * > & | adjacent_facets | ||
| ) | [private] |
Definition at line 1139 of file PartSurfFacetTool.cpp.
{
int i;
if (!curve_list.size() || !edge_list.size())
return CUBIT_FAILURE;
if (DEBUG_FLAG(145))
draw_edges( edge_list, CUBIT_WHITE_INDEX, true, true, CUBIT_WHITE_INDEX, false );
DLIList<CubitFacetData*> old_facets, new_facets;
DLIList<CubitFacetEdgeData*> dead_edge_ptrs;
PartitionCurve* curve = 0;
// All the curves in the attached coedge_list should belong
// to the same real curve and thus have a single continuous
// parameterization over the entire set of curves. Verify
// this now.
PartitionPoint *start_point, *end_point;
Curve* real_curve = get_real_curve(curve_list, start_point, end_point);
if (!real_curve)
{
PRINT_ERROR("Internal error at %s:%d\n", __FILE__, __LINE__ );
assert(false);
return CUBIT_FAILURE;
}
double period;
const bool periodic = real_curve->is_periodic(period);
const bool fwdparam = (periodic ? period > 0.0 : real_curve->start_param() < real_curve->end_param());
edge_list.reset();
CubitPoint *next_vtx, *curr_vtx;
if (edge_list.size() == 1)
{
next_vtx = edge_list.get()->point(1);
curr_vtx = edge_list.get()->point(0);
}
else
{
next_vtx = edge_list.get()->shared_point(edge_list.next());
curr_vtx = edge_list.get()->other_point(next_vtx);
}
assert(curr_vtx&&next_vtx);
// Special case: If curve_list is a closed loop of curves,
// a geometric check is required to determine if the passed
// list of facet edges is reversed wrt the curve list.
if (start_point == end_point)
{
CubitVector tangent, closest, start(curr_vtx->coordinates()), end(next_vtx->coordinates());
real_curve->closest_point( 0.5*(start+end), closest, &tangent );
if ((end - start) % tangent < 0.0)
edge_list.reverse();
}
// Otherwise just compare end coordinates
else
{
if ((start_point->coordinates() - curr_vtx->coordinates()).length_squared() >
(end_point->coordinates() - curr_vtx->coordinates()).length_squared())
{
if (edge_list.size() == 1)
{
next_vtx = curr_vtx;
curr_vtx = edge_list.get()->other_point(next_vtx);
}
else
{
edge_list.reverse();
edge_list.reset();
next_vtx = edge_list.get()->shared_point(edge_list.next());
curr_vtx = edge_list.get()->other_point(next_vtx);
}
assert(next_vtx&&curr_vtx);
}
}
DLIList<CubitFacetEdgeData*> edge_data_list;
CAST_LIST(edge_list, edge_data_list, CubitFacetEdgeData);
assert(edge_list.size() == edge_data_list.size());
// Find the subset of edges which belong on each curve.
// Begin with the first edge in the list, and the point
// at the end (opposite the curve start point) of the edge.
DLIList<CubitFacetEdgeData*> curve_edge_list; // edges for current curve
PartitionPoint* vertex = start_point; // end point of current curve
curve_list.reset();
edge_data_list.reset();
edge_data_list.reverse();
CubitFacetEdgeData* edge = edge_data_list.pop();
CubitPoint* point = start_point->facet_point(); // edge end point
point = edge->other_point(point);
if (!point)
{
PRINT_ERROR("Internal error at %s:%d\n", __FILE__, __LINE__);
assert(0);
return CUBIT_FAILURE;
}
// Iterate over all but the last curve
double prev_vtx_param = real_curve->start_param();
double prev_pt_param = real_curve->start_param();
for (i = curve_list.size() - 1; i--; )
{
curve_edge_list.clean_out();
curve = curve_list.get_and_step();
vertex = curve->other_point(vertex);
const CubitVector vtx_pos(vertex->coordinates());
double vtx_param = real_curve->u_from_position(vtx_pos);
double point_param = real_curve->u_from_position(point->coordinates());
if (periodic)
{
if ((vtx_param < prev_vtx_param) == fwdparam)
vtx_param += period;
if ((point_param < prev_pt_param) == fwdparam)
point_param += period;
prev_vtx_param = vtx_param;
prev_pt_param = point_param;
}
// Iterate until the edge "containing" the vertex
while ((vtx_param > point_param) == fwdparam)
{
// decrement edge count each time we add one of the
// original, input edges to the cuve edge list.
curve_edge_list.append(edge);
if (!edge_data_list.size()) { assert(0); return CUBIT_FAILURE; }
// Get the next edge and facet point
edge = edge_data_list.pop();
point = edge->other_point(point);
point_param = real_curve->u_from_position(point->coordinates());
if (periodic)
{
if ((point_param < prev_pt_param) == fwdparam)
point_param += period;
prev_pt_param = point_param;
}
}
CubitVector edge_pos;
edge->closest_point(vtx_pos, edge_pos);
CubitFacetEdgeData* new_edge;
CubitPoint* new_point = split_edge_closest( edge, edge_pos, 0.1*edge->length(), new_edge, facets );
if (!new_point)
return CUBIT_FAILURE;
// If the edge was split...
if (new_edge)
{
// If new_edge ends at the "end" point
// swap the edges.
if (new_edge->other_point(point))
std::swap(edge, new_edge);
// Put the earlier peice of the edge in the curve
// list. Keep the latter peice for the next curve
// iteration.
curve_edge_list.append(new_edge);
}
// If the input position was the same as the edge end point...
else if (new_point == point)
{
// Add edge to list for current curve and decrement count.
curve_edge_list.append(edge);
if (!edge_data_list.size()) { assert(0); return CUBIT_FAILURE; }
// Get the next edge and facet point for the next iteration.
edge = edge_data_list.pop();
point = edge->other_point(point);
}
// Move edge split point to location of vertex
#ifdef PART_SURF_REFACET
double d_sqr = (vtx_pos - edge_pos).length_squared();
bool close = d_sqr < (GEOMETRY_RESABS*GEOMETRY_RESABS);
old_facets.clean_out();
new_facets.clean_out();
if (close)
dynamic_cast<CubitPointData*>(new_point)->set(vtx_pos);
else if (!fix_move_point( new_point, vtx_pos, facets, old_facets, new_facets ))
return CUBIT_FAILURE;
assert(!old_facets.size() == !new_facets.size());
facets -= old_facets;
facets += new_facets;
#else
dynamic_cast<CubitPointData*>(new_point)->set(vtx_pos);
#endif
// Merge the points
CubitPointData* vtx_pointd = vertex->facet_point();
CubitPointData* new_pointd = dynamic_cast<CubitPointData*>(new_point);
if (vtx_pointd)
vtx_pointd->merge_points(new_pointd);
else
vertex->facet_point(new_pointd);
if (!curve->has_facet_data())
curve->set_facet_data(curve_edge_list);
else if(!seam_curve( curve_edge_list, curve, facets, &dead_edge_ptrs ))
return CUBIT_FAILURE;
while (dead_edge_ptrs.size())
{
CubitFacetEdgeData* edge = dead_edge_ptrs.pop();
boundary_set.erase(edge);
interior_set.erase(edge);
}
} // for(curve_list)
// Do last curve
curve = curve_list.get();
curve_edge_list.clean_out();
if (edge)
curve_edge_list.append(edge);
while (edge_data_list.size())
curve_edge_list.append(edge_data_list.pop());
if(!curve_edge_list.size()) { assert(0); return CUBIT_FAILURE; }
if (!curve->has_facet_data())
curve->set_facet_data(curve_edge_list);
else if(!seam_curve( curve_edge_list, curve, facets, &dead_edge_ptrs ))
return CUBIT_FAILURE;
while (dead_edge_ptrs.size())
{
CubitFacetEdgeData* edge = dead_edge_ptrs.pop();
boundary_set.erase(edge);
interior_set.erase(edge);
}
return CUBIT_SUCCESS;
}
| CubitStatus PartSurfFacetTool::seam_nonmanifold_curves | ( | DLIList< PartitionCurve * > & | partitions, |
| DLIList< CubitFacetData * > & | facet_list | ||
| ) | [private] |
Definition at line 898 of file PartSurfFacetTool.cpp.
{
// All the curves in the attached coedge_list should belong
// to the same real curve and thus have a single continuous
// parameterization over the entire set of curves. Verify
// this now.
PartitionPoint *start_point, *end_point;
Curve* real_curve = get_real_curve(curve_list, start_point, end_point);
if (!real_curve)
{
PRINT_ERROR("Internal error at %s:%d\n", __FILE__, __LINE__ );
assert(false);
return CUBIT_FAILURE;
}
// Assume caller has marked all interior edges with a '2'.
// Clear marks as we go to ensure we don't loop forever.
// Find chain of curves closest to real curve and ending
// at the end facet point.
CubitPoint* const start_vtx = start_point->facet_point();
CubitPoint* const end_vtx = end_point->facet_point();
assert(start_vtx&&end_vtx);
DLIList<CubitFacetEdge*> vtx_edges, seam_list;
CubitPoint* vtx = start_vtx;
do
{
vtx->edges(vtx_edges);
CubitFacetEdge* edge = 0;
double shortest_dist_sqr = CUBIT_DBL_MAX;
while( vtx_edges.size() )
{
CubitFacetEdge* curr = vtx_edges.pop();
//if (curr->marked() != 2 )
if (interior_set.count(curr) == 0)
continue;
if (curr->other_point(vtx) == end_vtx)
{
edge = curr;
break;
}
CubitVector closest, tangent;
CubitVector start(vtx->coordinates());
CubitVector end(curr->other_point(vtx)->coordinates());
real_curve->closest_point(0.5*(start+end), closest, &tangent);
if (tangent % (end-start) < 0.0)
continue;
real_curve->closest_point(end, closest);
closest -= end;
double dist_sqr = closest.length_squared();
if (dist_sqr < shortest_dist_sqr)
{
edge = curr;
shortest_dist_sqr = dist_sqr;
}
}
if (!edge)
{
PRINT_ERROR("Internal error at %s:%d:\n"
"Failed to associate facet edges with non-manofold curves.\n",
__FILE__, __LINE__ );
return CUBIT_FAILURE;
}
if (DEBUG_FLAG(145))
{
GfxDebug::draw_facet_edge( edge, CUBIT_MAGENTA_INDEX );
GfxDebug::flush();
}
seam_list.append(edge);
//edge->marked(0);
vtx = edge->other_point(vtx);
} while (vtx != end_vtx);
return seam_curves( curve_list, seam_list, facet_list );
}
| CubitStatus PartSurfFacetTool::split_edge | ( | CubitFacetEdge * | edge_to_split, |
| const CubitVector & | split_location, | ||
| CubitFacet * | edge_facet, | ||
| CubitPoint *& | new_split_point, | ||
| CubitFacetEdge *& | new_edge, | ||
| CubitFacet *& | new_facet | ||
| ) | [static] |
Remove small edges Misc. static utility functions
Definition at line 981 of file PartSurfFacetTool.cpp.
{
CubitVector v1, v2;
int i = 0, junk;
new_point = 0;
new_edge = 0;
new_facet = 0;
CubitFacet* split_facet = edge_facet;
if( !split_facet )
split_facet = old_edge->adj_facet(0);
else if( edge_facet->edge_index(old_edge) < 0 )
{ assert(0); return CUBIT_FAILURE; }
CubitPoint* pt1 = old_edge->point(0);
CubitPoint* pt2 = old_edge->point(1);
v1 = position - pt1->coordinates();
v2 = pt2->coordinates() - position;
assert( v1.length_squared() > GEOMETRY_RESABS*GEOMETRY_RESABS );
assert( v2.length_squared() > GEOMETRY_RESABS*GEOMETRY_RESABS );
#ifndef NDEBUG
double dot = v1 % v2;
assert( dot > 0 ); // projection of new point onto line lies outside edge.
// double cos_sqr = (dot * dot) / (v1.length_squared() * v2.length_squared());
// assert( cos_sqr > 0.99240387650610407 ); // angle less than 5 degrees
#endif
CubitPoint* new_pt = split_facet->split_edge( pt1, pt2, position );
new_edge = new_pt->shared_edge(pt2);
if( !new_edge ) { assert(0); return CUBIT_FAILURE; }
// find new facet and update for other split facets
CubitFacet *facet, *other_facet;
PartitionEntity* facet_owner;
while ( (facet = old_edge->adj_facet(i++)) ) {
CubitPoint* pt3 = facet->point( facet->edge_index(pt1,new_pt,junk) );
if( !pt3->shared_edge( new_pt ) )
new CubitFacetEdgeData( pt3, new_pt );
other_facet = facet->shared_facet( new_pt, pt3 );
if( !other_facet ) { assert(0); continue; }
if ( facet == edge_facet )
new_facet = other_facet;
else if( (facet_owner = TDVGFacetOwner::get(facet)) )
facet_owner->notify_split( facet, other_facet );
}
if( (facet_owner = TDVGFacetOwner::get( old_edge )) )
facet_owner->notify_split( old_edge, new_edge );
if( edge_facet )
assert(!!new_facet);
else
new_facet = 0;
new_point = new_pt;
return CUBIT_SUCCESS;
}
| CubitPoint * PartSurfFacetTool::split_edge_closest | ( | CubitFacetEdgeData * | edge, |
| const CubitVector & | pos, | ||
| double | tolerance, | ||
| CubitFacetEdgeData *& | new_edge, | ||
| DLIList< CubitFacetData * > & | new_facets | ||
| ) | [static] |
Definition at line 1954 of file PartSurfFacetTool.cpp.
{
// square of absolute tolerance
const double GEOM_TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS;
// tolerance as fraction of edge length.
const double TOL_SQR = tolerance < GEOM_TOL_SQR ? GEOM_TOL_SQR : tolerance * tolerance;
new_edge = 0;
const CubitVector start(old_edge->point(0)->coordinates());
const CubitVector end(old_edge->point(1)->coordinates());
// const CubitVector dir(end - start);
//const double fract = (dir % (pos - start)) / dir.length_squared();
// If near the start/end of the edge and start/end point is
// not already owned by some other vertex
const double start_sqr = (start - pos).length_squared();
const double end_sqr = (end - pos).length_squared();
if (start_sqr < TOL_SQR && !TDVGFacetOwner::get(old_edge->point(0)))
return old_edge->point(0);
else if (end_sqr < TOL_SQR && !TDVGFacetOwner::get(old_edge->point(1)))
return old_edge->point(1);
// Else if start/end of edge are same position as vertex
else if(start_sqr < GEOM_TOL_SQR)
return old_edge->point(0);
else if(end_sqr < GEOM_TOL_SQR)
return old_edge->point(1);
// Otherwise split the edge
CubitFacet* a_face = old_edge->adj_facet(0);
CubitFacetData* facet = dynamic_cast<CubitFacetData*>(a_face);
if (!facet)
return 0;
//CubitVector edge_pos((1.0-edge_param)*edge_start + edge_param*edge_end);
CubitPoint* start_pt = old_edge->point(0);
CubitPoint* end_pt = old_edge->point(1);
CubitPoint* new_pt = facet->split_edge( start_pt, end_pt, pos );
CubitFacetEdge* temp_edge = new_pt->shared_edge(end_pt);
new_edge = dynamic_cast<CubitFacetEdgeData*>(temp_edge);
if (!new_edge)
return 0;
// Update partition curve facetting
PartitionCurve* edge_owner = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(old_edge));
if (edge_owner)
edge_owner->notify_split(old_edge, new_edge);
// Update partition surfaces for split of adjacent facets
int i, junk = -1;
DLIList<CubitFacet*> facets(old_edge->num_adj_facets());
old_edge->facets(facets);
for ( i = facets.size(); i--; )
{
a_face = facets.get_and_step();
facet = dynamic_cast<CubitFacetData*>(a_face);
assert(!!facet);
int edge_index = facet->edge_index( start_pt, new_pt, junk );
CubitPoint* other_pt = facet->point( edge_index );
if (!other_pt->shared_edge( new_pt ))
new CubitFacetEdgeData( other_pt, new_pt );
CubitFacet* a_face = facet->shared_facet( new_pt, other_pt );
CubitFacetData* other_facet = dynamic_cast<CubitFacetData*>(a_face);
if (!other_facet) { assert(0); continue; }
PartitionEntity* owner = TDVGFacetOwner::get(facet);
#ifndef NDEBUG
PartitionSurface* surf = dynamic_cast<PartitionSurface*>(owner);
assert(!owner || surf);
#endif
if (owner)
owner->notify_split( facet, other_facet );
else
new_facets.append(other_facet);
}
return new_pt;
}
| void PartSurfFacetTool::validate_facets | ( | PartitionSurface * | surf | ) | [static] |
Debugging functions
Definition at line 22 of file PartSurfFacetTool.cpp.
{
int i, j, k;
DLIList<CubitFacetData*> facets;
DLIList<CubitFacet*> pt_facets, edge_facets;
DLIList<CubitFacetEdge*> pt_edges;
mySurface->get_facet_data(facets);
for( i = facets.size(); i--; )
{
CubitFacetData* facet = facets.get_and_step();
for ( j = 0; j < 3; j++ )
{
CubitFacetEdge* edge = facet->edge(j);
if ( !edge )
{
PRINT_ERROR("Facet with NULL edge.\n");
continue;
}
if ( PartitionEntity* ent = TDVGFacetOwner::get(edge) )
{
PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent);
if (!curve)
{
PRINT_ERROR("Facet edge owned by non-curve %s %p\n",
typeid(*ent).name(), (void*)ent);
GfxDebug::draw_line( edge->point(0)->coordinates(),
edge->point(1)->coordinates(),
CUBIT_RED_INDEX );
continue;
}
int edge_use_count = 0;
for ( k = 0; k < edge->num_adj_facets(); k++ )
if ( (const PartitionEntity*)TDVGFacetOwner::get(edge->adj_facet(k)) == mySurface )
edge_use_count++;
assert(edge_use_count);
int curve_use_count = 0;
int coedge_count = 0;
PartitionCoEdge* coedge = 0;
while (( coedge = curve->next_coedge(coedge) ))
{
if (coedge->get_loop())
{
coedge_count++;
if (coedge->get_loop()->get_surface() == mySurface)
curve_use_count++;
}
}
RefEdge* curve_owner = dynamic_cast<RefEdge*>(curve->topology_entity());
if ( coedge_count != edge->num_adj_facets() )
{
PRINT_ERROR("Curve %p (RefEdge %d): Curve in %d partition surfaces "
"has facet edge in %d facets.\n", (void*)curve,
curve_owner ? curve_owner->id() : 0,
coedge_count, edge->num_adj_facets() );
GfxDebug::draw_line( edge->point(0)->coordinates(),
edge->point(1)->coordinates(),
CUBIT_RED_INDEX );
}
if ( curve_use_count != edge_use_count )
{
PRINT_ERROR("Curve %p (RefEdge %d): Curve used in %d coedges of "
"this surface exists in %d facets of this surface.\n",
(void*)curve,
curve_owner ? curve_owner->id() : 0,
curve_use_count, edge_use_count );
GfxDebug::draw_line( edge->point(0)->coordinates(),
edge->point(1)->coordinates(),
CUBIT_RED_INDEX );
}
}
else // FacetEdge has no owner
{
if (edge->num_adj_facets() != 2)
{
PRINT_ERROR("Interior facet edge is %d-valent.\n", edge->num_adj_facets());
GfxDebug::draw_line( edge->point(0)->coordinates(),
edge->point(1)->coordinates(),
CUBIT_RED_INDEX );
}
}
bool found = false;
for ( k = 0; k < edge->num_adj_facets(); k++ )
{
CubitFacet* edge_facet = edge->adj_facet(k);
if( edge_facet == facet )
found = true;
int index = edge_facet->edge_index(edge);
if( index < 0 )
{
PRINT_ERROR("edge->facet link missing facet->edge link.\n");
continue;
}
CubitPoint* fp1 = edge_facet->point((index+1)%3);
CubitPoint* fp2 = edge_facet->point((index+2)%3);
int sense = 1;
if( fp1 == edge->point(1) && fp2 == edge->point(0) )
sense = -1;
else if( fp1 != edge->point(0) || fp2 != edge->point(1) )
{
PRINT_ERROR("Facet adjacent to edge does not contain edge end points.\n");
GfxDebug::draw_line( edge->point(0)->coordinates(),
edge->point(1)->coordinates(),
CUBIT_RED_INDEX );
continue;
}
if ( sense != edge_facet->edge_use(index) )
{
//PRINT_ERROR("Facet has incorrect edge use\n");
}
}
if( !found )
PRINT_ERROR("facet->edge link missing edge->facet link.\n");
}
for ( j = 0; j < 3; j++ )
{
CubitPoint* point = facet->point(j);
pt_facets.clean_out();
point->facets(pt_facets);
bool found = false;
for ( k = pt_facets.size(); k--; )
{
CubitFacet* pt_facet = pt_facets.get_and_step();
if ( pt_facet == facet )
found = true;
else if( pt_facet->point_index(point) < 0 )
PRINT_ERROR("point->facet link missing facet->point link.\n");
}
if( ! found )
PRINT_ERROR("facet->point link missing point->facet link.\n");
point->edges(pt_edges);
while (pt_edges.size())
{
CubitFacetEdge* edge = pt_edges.pop();
edge_facets.clean_out();
edge->facets(edge_facets);
int count = 0;
while (edge_facets.size())
if (TDVGFacetOwner::get(edge_facets.pop()) == mySurface)
count++;
bool draw = false;
if (count == 0) // not in this face
;
else if (PartitionEntity* ent = TDVGFacetOwner::get(edge))
{
PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent);
if (curve->is_nonmanifold(mySurface))
{
if (count != 2)
{
draw = true;
PRINT_ERROR("Edge on non-manifold curve contained in %d facets.\n", count);
}
}
else if (count != 1)
{
draw = true;
PRINT_ERROR("Boundary edge contained in %d facets.\n", count);
}
}
else if (count != 2)
{
draw = true;
PRINT_ERROR("Interior edge contained in %d facets.\n", count);
}
if (draw) {
CubitVector start = edge->point(0)->coordinates();
CubitVector step = 0.05 * (edge->point(1)->coordinates() - start);
for (int k = 0; k < 20; k++)
GfxDebug::draw_point( start + k * step, CUBIT_RED_INDEX );
GfxDebug::flush();
}
}
}
}
// Check loops for contiguous chains of facet edges.
DLIList<CubitFacetEdgeData*> curve_edges, loop_edges;
PartitionLoop* loop = 0;
while ((loop = mySurface->next_loop(loop)))
{
loop_edges.clean_out();
PartitionCoEdge* coedge = loop->first_coedge();
do {
PartitionCurve* curve = coedge->get_curve();
if (!curve->is_nonmanifold(mySurface))
{
curve_edges.clean_out();
curve->get_facet_data(curve_edges);
if (coedge->sense() == CUBIT_REVERSED)
curve_edges.reverse();
loop_edges += curve_edges;
}
coedge = loop->next_coedge(coedge);
} while (coedge != loop->first_coedge());
loop_edges.last();
CubitFacetEdgeData* prev = loop_edges.get_and_step();
PartitionCurve* prev_curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(prev));
for (int i = 0; i < loop_edges.size(); i++)
{
CubitFacetEdgeData* edge = loop_edges.get_and_step();
CubitPoint* shared = edge->shared_point(prev);
PartitionCurve* curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(edge));
if (!prev_curve || !curve)
{
PRINT_ERROR("Missing facet owner on boundary curve.\n");
prev_curve = curve;
prev = edge;
continue;
}
if (!shared)
{
PRINT_ERROR("Broken facet-edge chain at curve %p (RefEdge %d):\n"
" start of segment (%f,%f,%f)->(%f,%f,%f)\n",
(void*)curve, curve && dynamic_cast<RefEdge*>(curve->topology_entity())?
dynamic_cast<RefEdge*>(curve->topology_entity())->id() : 0,
edge->point(0)->coordinates().x(),
edge->point(0)->coordinates().y(),
edge->point(0)->coordinates().z(),
edge->point(1)->coordinates().x(),
edge->point(1)->coordinates().y(),
edge->point(1)->coordinates().z());
}
else if(PartitionPoint *pt = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(shared)))
{
if( (prev_curve == curve) &&
!(pt == curve->start_point() && pt == curve->end_point()) )
{
PRINT_ERROR("Edges at point %p (vertex %d) (%f,%f,%f) owned\n"
" by the same curve: %p (RefEdge %d)\n",
(void*)pt, dynamic_cast<RefVertex*>(pt->topology_entity()) ?
dynamic_cast<RefVertex*>(pt->topology_entity())->id() : 0,
pt->coordinates().x(), pt->coordinates().y(), pt->coordinates().z(),
(void*)curve, curve && dynamic_cast<RefEdge*>(curve->topology_entity())?
dynamic_cast<RefEdge*>(curve->topology_entity())->id() : 0);
}
else if (!curve->other_point(pt))
{
PRINT_ERROR("Edge owner curve %p (RefEdge %d) at point %p \n"
" (vertex %d) (%f,%f,%f) doesn't match topology\n",
(void*)curve, curve && dynamic_cast<RefEdge*>(curve->topology_entity())?
dynamic_cast<RefEdge*>(curve->topology_entity())->id() : 0,
(void*)pt, dynamic_cast<RefVertex*>(pt->topology_entity()) ?
dynamic_cast<RefVertex*>(pt->topology_entity())->id() : 0,
pt->coordinates().x(), pt->coordinates().y(), pt->coordinates().z());
}
else if(!prev_curve->other_point(pt))
{
PRINT_ERROR("Edge owner curve %p (RefEdge %d) at point %p \n"
" (vertex %d) (%f,%f,%f) doesn't match topology\n",
(void*)prev_curve, prev_curve && dynamic_cast<RefEdge*>(prev_curve->topology_entity())?
dynamic_cast<RefEdge*>(prev_curve->topology_entity())->id() : 0,
(void*)pt, dynamic_cast<RefVertex*>(pt->topology_entity()) ?
dynamic_cast<RefVertex*>(pt->topology_entity())->id() : 0,
pt->coordinates().x(), pt->coordinates().y(), pt->coordinates().z());
}
}
else if (prev_curve != curve)
{
PRINT_ERROR("Missing point-owner at transition between\n"
" curve %p (RefEdge %d) and curve %p (RefEdge %d):\n"
" at location (%f,%f,%f)\n",
(void*)curve, curve && dynamic_cast<RefEdge*>(curve->topology_entity())?
dynamic_cast<RefEdge*>(curve->topology_entity())->id() : 0,
(void*)prev_curve, prev_curve && dynamic_cast<RefEdge*>(prev_curve->topology_entity())?
dynamic_cast<RefEdge*>(prev_curve->topology_entity())->id() : 0,
shared->coordinates().x(),
shared->coordinates().y(),
shared->coordinates().z() );
}
prev = edge;
prev_curve = curve;
}
}
}
std::set<CubitFacetEdge*> PartSurfFacetTool::boundary_set [private] |
Definition at line 243 of file PartSurfFacetTool.hpp.
std::set<CubitFacetEdge*> PartSurfFacetTool::interior_set [private] |
Definition at line 243 of file PartSurfFacetTool.hpp.
PartitionSurface* const PartSurfFacetTool::mySurface [private] |
Definition at line 244 of file PartSurfFacetTool.hpp.