mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-30 23:57:58 +08:00
Sync changes from upstream repository
Co-authored-by: Steve Baer <steve@mcneel.com> Co-authored-by: Nathan Letwory <nathan@mcneel.com> Co-authored-by: Dale Lear <dalelear@mcneel.com>
This commit is contained in:
committed by
Will Pearson
parent
b844466e88
commit
799431a63b
@@ -26,101 +26,14 @@
|
||||
////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
////unsigned int ON_SubD::SectorEdgeCount(
|
||||
//// const class ON_SubDSectorIterator& sit
|
||||
//// )
|
||||
////{
|
||||
//// ON_SubDSectorIterator sit_local(sit);
|
||||
//// const ON_SubDVertex* center_vertex = sit_local.CenterVertex();
|
||||
//// if ( nullptr == center_vertex )
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
//// if ( 0 == center_vertex->m_edge_count && 0 == center_vertex->m_face_count )
|
||||
//// return 0; // not an error
|
||||
//// if ( center_vertex->m_edge_count < 2 || center_vertex->m_face_count < 1 || nullptr == center_vertex->m_edges || nullptr == center_vertex->m_faces )
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
//// const ON_SubDFace* face0 = sit_local.CurrentFace();
|
||||
//// const ON_SubDEdge* edge0 = sit_local.CurrentEdge(0);
|
||||
//// const ON_SubDEdge* e1 = sit_local.CurrentEdge(1);
|
||||
//// if ( nullptr == face0 || nullptr == edge0 || nullptr == e1 || edge0 == e1 )
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
////
|
||||
//// const ON_SubDFace* f0 = face0;
|
||||
//// const unsigned int N = center_vertex->m_edge_count;
|
||||
//// unsigned int edge_count = 0;
|
||||
//// while (edge_count <= N) // edge_count <= N used to prevent infinite recursion on damaged topology
|
||||
//// {
|
||||
//// const ON_SubDFace* f1 = sit_local.NextFace(true);
|
||||
//// if (f0 == f1 || f1 == face0)
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
//// const ON_SubDEdge* e0 = sit_local.CurrentEdge(0);
|
||||
//// if (e0 != e1)
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
//// if (f0 == face0 && e0 == edge0)
|
||||
//// return edge_count; // back to where we started
|
||||
////
|
||||
//// edge_count++;
|
||||
//// e1 = sit_local.CurrentEdge(1);
|
||||
//// if (e0 == e1)
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
////
|
||||
//// if (e1 == edge0)
|
||||
//// {
|
||||
//// // edge0 should be a crease and center_vertex should be a dart
|
||||
//// if (ON_SubD::EdgeTag::Crease == edge0->m_edge_tag)
|
||||
//// {
|
||||
//// f1 = sit_local.NextFace(true);
|
||||
//// if (nullptr == f1)
|
||||
//// return edge_count;
|
||||
//// }
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
//// }
|
||||
////
|
||||
//// if (nullptr == e1)
|
||||
//// {
|
||||
//// // e0 should be a crease and f1 should be null
|
||||
//// if ( ON_SubD::EdgeTag::Crease != e0->m_edge_tag && 2 == e0->m_face_count)
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
////
|
||||
//// if (nullptr != f1)
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
////
|
||||
//// sit_local = sit;
|
||||
//// f0 = face0;
|
||||
//// e1 = edge0;
|
||||
//// while (edge_count <= N)
|
||||
//// {
|
||||
//// f1 = sit_local.PrevFace(true);
|
||||
//// e0 = sit_local.CurrentEdge(1);
|
||||
//// if (e0 != e1)
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
//// e1 = sit_local.CurrentEdge(0);
|
||||
//// if (nullptr == e1)
|
||||
//// {
|
||||
//// // e0 should be a crease, e1 and f1 should be null
|
||||
//// if ( nullptr == f1)
|
||||
//// return edge_count; // hit matching crease
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
//// }
|
||||
//// if ( e1 == edge0)
|
||||
//// return ON_SUBD_RETURN_ERROR(0);
|
||||
//// edge_count++;
|
||||
//// }
|
||||
//// return ON_SUBD_RETURN_ERROR(0); // damaged topology
|
||||
//// }
|
||||
//// }
|
||||
////
|
||||
//// return ON_SUBD_RETURN_ERROR(0); // damaged topology
|
||||
////}
|
||||
|
||||
unsigned int ON_SubD::GetQuadSectorPointRing(
|
||||
ON_SubD::SubDType subd_type,
|
||||
bool bFirstPass,
|
||||
bool bSecondPass,
|
||||
const ON_SubDVertex* center_vertex,
|
||||
size_t component_ring_count,
|
||||
const ON_SubDComponentPtr* component_ring,
|
||||
size_t point_ring_stride,
|
||||
double* point_ring
|
||||
size_t component_ring_count,
|
||||
double* point_ring,
|
||||
size_t point_ring_stride
|
||||
)
|
||||
{
|
||||
//// NO VALIDATION CHECKS
|
||||
@@ -167,7 +80,7 @@ unsigned int ON_SubD::GetQuadSectorPointRing(
|
||||
if ( false == bSecondPass)
|
||||
return ON_SUBD_RETURN_ERROR(0); // subdivision not permitted
|
||||
|
||||
if (false == vertex0->GetSubdivisionPoint(subd_type, bUseSavedSubdivisionPoint, subP))
|
||||
if (false == vertex0->GetSubdivisionPoint(subP))
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
Q = subP;
|
||||
@@ -191,7 +104,7 @@ unsigned int ON_SubD::GetQuadSectorPointRing(
|
||||
|
||||
if (0 == pass)
|
||||
{
|
||||
if (ON_SubD::EdgeTag::X == edge->m_edge_tag)
|
||||
if (ON_SubD::EdgeTag::SmoothX == edge->m_edge_tag)
|
||||
break; // need to use subdivision point in 2nd pass
|
||||
if (ON_SubD::VertexTag::Smooth == vertex->m_vertex_tag
|
||||
|| ON_SubD::EdgeTag::Crease == edge->m_edge_tag
|
||||
@@ -205,7 +118,7 @@ unsigned int ON_SubD::GetQuadSectorPointRing(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (false == edge->GetSubdivisionPoint(subd_type, bUseSavedSubdivisionPoint, subP))
|
||||
if (false == edge->GetSubdivisionPoint(subP))
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
Q = subP;
|
||||
}
|
||||
@@ -262,7 +175,7 @@ unsigned int ON_SubD::GetQuadSectorPointRing(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (false == face->GetSubdivisionPoint(subd_type, bUseSavedSubdivisionPoint, subP))
|
||||
if (false == face->GetSubdivisionPoint(subP))
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
}
|
||||
P[0] = Q[0];
|
||||
@@ -281,129 +194,6 @@ unsigned int ON_SubD::GetQuadSectorPointRing(
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
}
|
||||
|
||||
|
||||
unsigned int ON_SubD::GetTriSectorPointRing(
|
||||
ON_SubD::SubDType subd_type,
|
||||
bool bFirstPass,
|
||||
bool bSecondPass,
|
||||
const ON_SubDVertex* vertex0,
|
||||
size_t component_ring_count,
|
||||
const ON_SubDComponentPtr* component_ring,
|
||||
size_t point_ring_stride,
|
||||
double* point_ring
|
||||
)
|
||||
{
|
||||
//// NO VALIDATION CHECKS
|
||||
//// CALLER INSURES INPUT HAS NON-nullptr POINTERS AND CORRECT COUNTS
|
||||
|
||||
double subP[3];
|
||||
const double* Q = nullptr;
|
||||
|
||||
const unsigned int N = ON_SubD::ComponentRingEdgeCount(component_ring_count);
|
||||
const unsigned int point_ring_count = 1 + N;
|
||||
const double* point_ring1 = point_ring + (point_ring_count*point_ring_stride);
|
||||
|
||||
const bool bUseSavedSubdivisionPoint = bSecondPass;
|
||||
|
||||
for (unsigned int pass = (bFirstPass ? 0U : 1U); pass < (bSecondPass ? 2U : 1U); pass++)
|
||||
{
|
||||
double* P = point_ring;
|
||||
|
||||
const ON_SubDEdgePtr* edges;
|
||||
const ON_SubDFacePtr* faces;
|
||||
size_t element_stride;
|
||||
|
||||
if (nullptr != vertex0)
|
||||
{
|
||||
edges = vertex0->m_edges;
|
||||
faces = (const ON_SubDFacePtr*)(vertex0->m_faces);
|
||||
element_stride = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex0 = component_ring[0].Vertex();
|
||||
edges = (const ON_SubDEdgePtr*)(component_ring+1);
|
||||
faces = (const ON_SubDFacePtr*)(component_ring+2);
|
||||
element_stride = 2;
|
||||
}
|
||||
|
||||
if (0 == pass)
|
||||
Q = vertex0->m_P;
|
||||
else
|
||||
{
|
||||
if ( false == bSecondPass)
|
||||
return ON_SUBD_RETURN_ERROR(0); // subdivision not permitted
|
||||
|
||||
if (false == vertex0->GetSubdivisionPoint(subd_type, bUseSavedSubdivisionPoint, subP))
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
Q = subP;
|
||||
}
|
||||
P[0] = Q[0];
|
||||
P[1] = Q[1];
|
||||
P[2] = Q[2];
|
||||
P += point_ring_stride;
|
||||
|
||||
for (unsigned int i = 0; i < N; i++, edges += element_stride, faces += element_stride)
|
||||
{
|
||||
// Get edge point
|
||||
ON__UINT_PTR eptr = edges->m_ptr;
|
||||
const ON_SubDEdge* edge = ON_SUBD_EDGE_POINTER(eptr);
|
||||
if (nullptr == edge)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
eptr = 1 - ON_SUBD_EDGE_DIRECTION(eptr);
|
||||
const ON_SubDVertex* vertex = edge->m_vertex[eptr];
|
||||
if (nullptr == vertex)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
if (0 == pass)
|
||||
{
|
||||
if (ON_SubD::EdgeTag::X == edge->m_edge_tag)
|
||||
break; // need 2nd pass
|
||||
if (ON_SubD::VertexTag::Smooth == vertex->m_vertex_tag
|
||||
|| ON_SubD::EdgeTag::Crease == edge->m_edge_tag
|
||||
|| 0.5 == edge->m_sector_coefficient[eptr]
|
||||
)
|
||||
{
|
||||
Q = vertex->m_P;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; // need 2nd pass
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (false == edge->GetSubdivisionPoint(subd_type, bUseSavedSubdivisionPoint, subP))
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
Q = subP;
|
||||
}
|
||||
P[0] = Q[0];
|
||||
P[1] = Q[1];
|
||||
P[2] = Q[2];
|
||||
P += point_ring_stride;
|
||||
|
||||
if (point_ring1 == P)
|
||||
{
|
||||
// success on a sector with crease boundary
|
||||
return point_ring_count;
|
||||
}
|
||||
|
||||
const ON_SubDFace* face = ON_SUBD_FACE_POINTER(faces->m_ptr);
|
||||
if (3 != face->m_edge_count)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
}
|
||||
|
||||
if (point_ring1 == P)
|
||||
{
|
||||
// success on a smooth sector
|
||||
return point_ring_count;
|
||||
}
|
||||
}
|
||||
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
}
|
||||
|
||||
unsigned int ON_SubD::ComponentRingEdgeCount(size_t component_ring_count)
|
||||
{
|
||||
const unsigned int N
|
||||
@@ -424,8 +214,8 @@ unsigned int ON_SubD::ComponentRingFaceCount(size_t component_ring_count)
|
||||
}
|
||||
|
||||
bool ON_SubD::ComponentRingIsValid(
|
||||
size_t component_ring_count,
|
||||
const ON_SubDComponentPtr* component_ring
|
||||
const ON_SubDComponentPtr* component_ring,
|
||||
size_t component_ring_count
|
||||
)
|
||||
{
|
||||
if (nullptr == component_ring || component_ring_count < 4)
|
||||
@@ -457,14 +247,14 @@ bool ON_SubD::ComponentRingIsValid(
|
||||
const ON_SubDEdge* edge = component_ring[component_ring_index].Edge();
|
||||
if ( nullptr == edge)
|
||||
return ON_SUBD_RETURN_ERROR(false);
|
||||
if (vertex != edge->m_vertex[component_ring[component_ring_index].ComponentMark()])
|
||||
if (vertex != edge->m_vertex[component_ring[component_ring_index].ComponentDirection()])
|
||||
return ON_SUBD_RETURN_ERROR(false);
|
||||
|
||||
if (0 == i)
|
||||
{
|
||||
if (edge0_tag != edge->m_edge_tag)
|
||||
{
|
||||
if ( ON_SubD::EdgeTag::Smooth != edge0_tag || ON_SubD::EdgeTag::X != edge->m_edge_tag )
|
||||
if ( ON_SubD::EdgeTag::Smooth != edge0_tag || ON_SubD::EdgeTag::SmoothX != edge->m_edge_tag )
|
||||
return ON_SUBD_RETURN_ERROR(false);
|
||||
}
|
||||
}
|
||||
@@ -472,7 +262,7 @@ bool ON_SubD::ComponentRingIsValid(
|
||||
{
|
||||
if (edge1_tag != edge->m_edge_tag)
|
||||
{
|
||||
if ( ON_SubD::EdgeTag::Smooth != edge1_tag || ON_SubD::EdgeTag::X != edge->m_edge_tag )
|
||||
if ( ON_SubD::EdgeTag::Smooth != edge1_tag || ON_SubD::EdgeTag::SmoothX != edge->m_edge_tag )
|
||||
return ON_SUBD_RETURN_ERROR(false);
|
||||
}
|
||||
if ( ON_SubD::EdgeTag::Crease == edge1_tag)
|
||||
@@ -500,7 +290,6 @@ bool ON_SubD::ComponentRingIsValid(
|
||||
}
|
||||
|
||||
unsigned int ON_SubD::GetSectorPointRing(
|
||||
ON_SubD::SubDType subd_type,
|
||||
bool bSubdivideIfNeeded,
|
||||
size_t component_ring_count,
|
||||
const ON_SubDComponentPtr* component_ring,
|
||||
@@ -517,7 +306,7 @@ unsigned int ON_SubD::GetSectorPointRing(
|
||||
ON_3dPoint* point_ring_array = point_ring.Reserve(point_ring_capacity);
|
||||
if ( nullptr == point_ring_array)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
unsigned int point_ring_count = GetSectorPointRing(subd_type, bSubdivideIfNeeded, component_ring_count, component_ring, point_ring_capacity, 3, &point_ring_array[0].x);
|
||||
unsigned int point_ring_count = GetSectorPointRing( bSubdivideIfNeeded, component_ring, component_ring_count, &point_ring_array[0].x, point_ring_capacity, 3);
|
||||
if (point_ring_count > 0)
|
||||
{
|
||||
point_ring.SetCount(point_ring_count);
|
||||
@@ -528,36 +317,26 @@ unsigned int ON_SubD::GetSectorPointRing(
|
||||
|
||||
|
||||
unsigned int ON_SubD::GetSectorSubdivsionPointRing(
|
||||
ON_SubD::SubDType subd_type,
|
||||
size_t component_ring_count,
|
||||
const ON_SubDComponentPtr* component_ring,
|
||||
size_t component_ring_count,
|
||||
double* subd_point_ring,
|
||||
size_t subd_point_ring_capacity,
|
||||
size_t subd_point_ring_stride,
|
||||
double* subd_point_ring
|
||||
size_t subd_point_ring_stride
|
||||
)
|
||||
{
|
||||
if (false == ComponentRingIsValid(component_ring_count,component_ring))
|
||||
if (false == ComponentRingIsValid(component_ring,component_ring_count))
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
const unsigned int K = ON_SubD::FacetEdgeCount(subd_type);
|
||||
if ( 3 != K && 4 != K )
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
const unsigned int N = ON_SubD::ComponentRingEdgeCount(component_ring_count);
|
||||
const unsigned int F = ON_SubD::ComponentRingFaceCount(component_ring_count);
|
||||
const unsigned int point_ring_count = N + (K-3)*F;
|
||||
const unsigned int point_ring_count = N + F;
|
||||
if ( point_ring_count > subd_point_ring_capacity || nullptr == subd_point_ring)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
const bool bFirstPass = false;
|
||||
const bool bSecondPass = true;
|
||||
unsigned int rc;
|
||||
if ( 3 == K )
|
||||
rc = GetTriSectorPointRing(subd_type,bFirstPass,bSecondPass,nullptr,component_ring_count,component_ring,subd_point_ring_stride,subd_point_ring);
|
||||
else if ( 4 == K )
|
||||
rc = GetQuadSectorPointRing(subd_type,bFirstPass,bSecondPass,nullptr,component_ring_count,component_ring,subd_point_ring_stride,subd_point_ring);
|
||||
else
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
unsigned int rc = GetQuadSectorPointRing(bFirstPass,bSecondPass,nullptr,component_ring,component_ring_count, subd_point_ring, subd_point_ring_stride);
|
||||
|
||||
if (0 == rc)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
@@ -567,9 +346,8 @@ unsigned int ON_SubD::GetSectorSubdivsionPointRing(
|
||||
}
|
||||
|
||||
unsigned int ON_SubD::GetSectorSubdivisionPointRing(
|
||||
ON_SubD::SubDType subd_type,
|
||||
size_t component_ring_count,
|
||||
const ON_SubDComponentPtr* component_ring,
|
||||
size_t component_ring_count,
|
||||
ON_SimpleArray<ON_3dPoint>& subd_point_ring
|
||||
)
|
||||
{
|
||||
@@ -583,7 +361,7 @@ unsigned int ON_SubD::GetSectorSubdivisionPointRing(
|
||||
ON_3dPoint* subd_point_ring_array = subd_point_ring.Reserve(subd_point_ring_capacity);
|
||||
if ( nullptr == subd_point_ring_array)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
unsigned int subd_point_ring_count = GetSectorSubdivsionPointRing(subd_type, component_ring_count, component_ring, subd_point_ring_capacity, 3, &subd_point_ring_array[0].x);
|
||||
unsigned int subd_point_ring_count = GetSectorSubdivsionPointRing(component_ring, component_ring_count, &subd_point_ring_array[0].x, subd_point_ring_capacity, 3);
|
||||
if (subd_point_ring_count > 0)
|
||||
{
|
||||
subd_point_ring.SetCount(subd_point_ring_count);
|
||||
@@ -593,37 +371,26 @@ unsigned int ON_SubD::GetSectorSubdivisionPointRing(
|
||||
}
|
||||
|
||||
unsigned int ON_SubD::GetSectorPointRing(
|
||||
ON_SubD::SubDType subd_type,
|
||||
bool bSubdivideIfNeeded,
|
||||
size_t component_ring_count,
|
||||
const ON_SubDComponentPtr* component_ring,
|
||||
size_t component_ring_count,
|
||||
double* point_ring,
|
||||
size_t point_ring_capacity,
|
||||
size_t point_ring_stride,
|
||||
double* point_ring
|
||||
size_t point_ring_stride
|
||||
)
|
||||
{
|
||||
if (false == ComponentRingIsValid(component_ring_count,component_ring))
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
const unsigned int K = ON_SubD::FacetEdgeCount(subd_type);
|
||||
if ( 3 != K && 4 != K )
|
||||
if (false == ComponentRingIsValid(component_ring,component_ring_count))
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
const unsigned int N = ON_SubD::ComponentRingEdgeCount(component_ring_count);
|
||||
const unsigned int F = ON_SubD::ComponentRingFaceCount(component_ring_count);
|
||||
const unsigned int point_ring_count = N + (K-3)*F;
|
||||
const unsigned int point_ring_count = N + F;
|
||||
if ( point_ring_count > point_ring_capacity || nullptr == point_ring)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
const bool bFirstPass = true;
|
||||
const bool bSecondPass = bSubdivideIfNeeded;
|
||||
unsigned int rc;
|
||||
if ( 3 == K )
|
||||
rc = GetTriSectorPointRing(subd_type,bFirstPass,bSecondPass,nullptr,component_ring_count,component_ring,point_ring_stride,point_ring);
|
||||
else if ( 4 == K )
|
||||
rc = GetQuadSectorPointRing(subd_type,bFirstPass,bSecondPass,nullptr,component_ring_count,component_ring,point_ring_stride,point_ring);
|
||||
else
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
unsigned int rc = GetQuadSectorPointRing(bFirstPass,bSecondPass,nullptr, component_ring,component_ring_count, point_ring,point_ring_stride);
|
||||
|
||||
if (0 == rc)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
@@ -633,18 +400,13 @@ unsigned int ON_SubD::GetSectorPointRing(
|
||||
|
||||
|
||||
unsigned int ON_SubD::GetSectorPointRing(
|
||||
ON_SubD::SubDType subd_type,
|
||||
bool bSubdivideIfNeeded,
|
||||
const class ON_SubDSectorIterator& sit,
|
||||
double* point_ring,
|
||||
size_t point_ring_capacity,
|
||||
size_t point_ring_stride,
|
||||
double* point_ring
|
||||
size_t point_ring_stride
|
||||
)
|
||||
{
|
||||
const ON_SubD::FacetType facet_type = ON_SubD::FacetTypeFromSubDType(subd_type);
|
||||
if ( ON_SubD::FacetType::Quad != facet_type && ON_SubD::FacetType::Tri != facet_type )
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
const ON_SubDVertex* center_vertex = sit.CenterVertex();
|
||||
if ( nullptr == center_vertex )
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
@@ -662,15 +424,12 @@ unsigned int ON_SubD::GetSectorPointRing(
|
||||
}
|
||||
|
||||
unsigned int point_ring_count = 0;
|
||||
unsigned int component_ring_count = ON_SubD::GetSectorComponentRing(sit,component_ring_capacity,component_ring);
|
||||
unsigned int component_ring_count = ON_SubD::GetSectorComponentRing(sit, component_ring,component_ring_capacity);
|
||||
if (component_ring_count > 0)
|
||||
{
|
||||
const bool bFirstPass = true;
|
||||
const bool bSecondPass = bSubdivideIfNeeded;
|
||||
point_ring_count =
|
||||
( ON_SubD::FacetType::Quad == facet_type )
|
||||
? ON_SubD::GetQuadSectorPointRing(subd_type,bFirstPass,bSecondPass,nullptr,component_ring_count,component_ring,point_ring_stride,point_ring)
|
||||
: ON_SubD::GetTriSectorPointRing(subd_type,bFirstPass,bSecondPass,nullptr,component_ring_count,component_ring,point_ring_stride,point_ring);
|
||||
point_ring_count = ON_SubD::GetQuadSectorPointRing( bFirstPass, bSecondPass, nullptr, component_ring, component_ring_count, point_ring, point_ring_stride);
|
||||
}
|
||||
|
||||
if ( component_ring != stack_component_ring)
|
||||
@@ -680,7 +439,6 @@ unsigned int ON_SubD::GetSectorPointRing(
|
||||
}
|
||||
|
||||
unsigned int ON_SubD::GetSectorPointRing(
|
||||
ON_SubD::SubDType subd_type,
|
||||
bool bSubdivideIfNeeded,
|
||||
const class ON_SubDSectorIterator& sit,
|
||||
ON_SimpleArray<ON_3dPoint>& point_ring
|
||||
@@ -694,7 +452,7 @@ unsigned int ON_SubD::GetSectorPointRing(
|
||||
ON_3dPoint* point_ring_array = point_ring.Reserve(point_ring_capacity);
|
||||
if ( nullptr == point_ring_array)
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
unsigned int point_ring_count = GetSectorPointRing(subd_type, bSubdivideIfNeeded, sit, point_ring_capacity, 3, &point_ring_array[0].x);
|
||||
unsigned int point_ring_count = GetSectorPointRing( bSubdivideIfNeeded, sit, &point_ring_array[0].x, point_ring_capacity, 3);
|
||||
if (point_ring_count > 0)
|
||||
{
|
||||
point_ring.SetCount(point_ring_count);
|
||||
@@ -710,7 +468,7 @@ static double Subdivide_CenterVertexSectorWeight(
|
||||
{
|
||||
if ( ON_SubD::EdgeTag::Crease == edge0->m_edge_tag)
|
||||
return ON_SubDSectorType::IgnoredSectorWeight;
|
||||
if (ON_SubD::EdgeTag::Smooth == edge0->m_edge_tag || ON_SubD::EdgeTag::X == edge0->m_edge_tag)
|
||||
if (ON_SubD::EdgeTag::Smooth == edge0->m_edge_tag || ON_SubD::EdgeTag::SmoothX == edge0->m_edge_tag)
|
||||
{
|
||||
if (vertex0 == edge0->m_vertex[0])
|
||||
return edge0->m_sector_coefficient[0];
|
||||
@@ -721,16 +479,19 @@ static double Subdivide_CenterVertexSectorWeight(
|
||||
}
|
||||
|
||||
const ON_SubDVertex* ON_SubD::SubdivideSector(
|
||||
ON_SubD::SubDType subd_type,
|
||||
const ON_SubDVertex* center_vertex,
|
||||
size_t component_ring_count,
|
||||
const ON_SubDComponentPtr* component_ring,
|
||||
size_t component_ring_count,
|
||||
ON_SubD_FixedSizeHeap& fsh
|
||||
)
|
||||
{
|
||||
const unsigned int N = (nullptr != center_vertex) ? center_vertex->m_edge_count : ON_SubD::ComponentRingEdgeCount(component_ring_count);
|
||||
const unsigned int F = (nullptr != center_vertex) ? center_vertex->m_face_count : ON_SubD::ComponentRingFaceCount(component_ring_count);
|
||||
|
||||
if ( N < 2 )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
if ( F != N && F+1 != N )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
|
||||
size_t element_stride;
|
||||
const ON_SubDEdgePtr* edges;
|
||||
const ON_SubDFacePtr* faces;
|
||||
@@ -751,65 +512,74 @@ const ON_SubDVertex* ON_SubD::SubdivideSector(
|
||||
edges = center_vertex->m_edges;
|
||||
faces = (const ON_SubDFacePtr*)(center_vertex->m_faces);
|
||||
element_stride = 1;
|
||||
if ( F != N && F+1 != N )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
}
|
||||
|
||||
// smooth and dart sectors have F = N
|
||||
// crease and corner have F = N-1
|
||||
if (F != (center_vertex->IsCreaseOrCorner() ? (N-1) : N) )
|
||||
{
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
}
|
||||
|
||||
const ON_SubD::EdgeTag edge0_tag = (F+1 == N) ? ON_SubD::EdgeTag::Crease : ON_SubD::EdgeTag::Smooth;
|
||||
|
||||
const unsigned int face_edge_count = ON_SubD::FacetEdgeCount(subd_type);
|
||||
if ( 3 != face_edge_count && 4 != face_edge_count )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
const unsigned int K = face_edge_count-1;
|
||||
//const unsigned int face_edge_count = 4;
|
||||
const unsigned int K = 3;
|
||||
|
||||
const ON_SubDEdge* edge0 = edges->Edge();
|
||||
if ( nullptr == edge0)
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
edges += element_stride;
|
||||
|
||||
if ( edge0_tag != edge0->m_edge_tag)
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
if (ON_SubD::EdgeTag::Smooth == edge0_tag)
|
||||
{
|
||||
if (false == edge0->IsSmooth() )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (edge0_tag != edge0->m_edge_tag)
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
}
|
||||
|
||||
const ON_SubDFace* face0 = faces->Face();
|
||||
if ( nullptr == face0)
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
edges += element_stride;
|
||||
|
||||
if ( false == fsh.ReserveSubDWorkspace(N+1,K*N,N,(3*K+1)*N))
|
||||
if ( false == fsh.ReserveSubDWorkspace(N) )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
|
||||
const bool bUseSavedSubdivisionPoint = true;
|
||||
|
||||
ON_SubDVertex* v1[4] = {};
|
||||
ON_SubDEdge* e1[4] = {};
|
||||
ON_SubDEdgePtr e1[4] = {};
|
||||
ON_SubDEdgePtr f1epts[4] = {};
|
||||
|
||||
const ON_SubDVertex* vertex0 = center_vertex;
|
||||
|
||||
v1[0] = fsh.AllocateVertex(vertex0,subd_type,bUseSavedSubdivisionPoint,N,N);
|
||||
v1[0] = fsh.AllocateVertex(vertex0,N);
|
||||
if ( nullptr == v1[0])
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
//v1[0]->m_vertex_edge_order = ON_SubD::VertexEdgeOrder::radial;
|
||||
|
||||
ON_SubDVertex* vertex1 = fsh.AllocateVertex(edge0,subd_type,bUseSavedSubdivisionPoint,3,2);
|
||||
ON_SubDVertex* vertex1 = fsh.AllocateVertex(edge0);
|
||||
if ( nullptr == vertex1)
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
|
||||
// at_crease weight is used when the cooresponding vertex is a crease.
|
||||
// Otherwise, fsh.AllocateEdge() ignores at_crease_weight.
|
||||
ON_SubD::EdgeTag edge1_tag = (ON_SubD::EdgeTag::X == edge0_tag) ? ON_SubD::EdgeTag::Smooth : edge0_tag;
|
||||
ON_SubD::EdgeTag edge1_tag = (ON_SubD::EdgeTag::SmoothX == edge0_tag) ? ON_SubD::EdgeTag::Smooth : edge0_tag;
|
||||
const double at_crease_weight
|
||||
= ON_SubD::EdgeTag::Crease == edge1_tag
|
||||
? ON_SubDSectorType::CreaseSectorWeight(subd_type,5-K)
|
||||
? ON_SubDSectorType::CreaseSectorWeight(5-K)
|
||||
: ON_SubDSectorType::IgnoredSectorWeight;
|
||||
ON_SubDEdge* edge1 = fsh.AllocateEdge(v1[0], Subdivide_CenterVertexSectorWeight(edge0,vertex0), vertex1, ON_SubDSectorType::IgnoredSectorWeight );
|
||||
if ( nullptr == edge1)
|
||||
ON_SubDEdgePtr edge1 = fsh.AllocateEdge(v1[0], Subdivide_CenterVertexSectorWeight(edge0,vertex0), vertex1, ON_SubDSectorType::IgnoredSectorWeight );
|
||||
if (edge1.IsNull())
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
edge1->m_edge_tag = edge1_tag;
|
||||
edge1.Edge()->m_edge_tag = edge1_tag;
|
||||
|
||||
v1[1] = vertex1;
|
||||
e1[0] = edge1;
|
||||
f1epts[0] = ON_SubDEdgePtr::Create(e1[0],0);
|
||||
f1epts[0] = e1[0];
|
||||
edge1_tag = ON_SubD::EdgeTag::Smooth;
|
||||
|
||||
for (unsigned int i = 1; i < N; i++, edges += element_stride, faces += element_stride)
|
||||
@@ -834,36 +604,26 @@ const ON_SubDVertex* ON_SubD::SubdivideSector(
|
||||
|
||||
if (nullptr == v1[K])
|
||||
{
|
||||
v1[K] = fsh.AllocateVertex(edge0, subd_type, bUseSavedSubdivisionPoint, 3, 2);
|
||||
v1[K] = fsh.AllocateVertex(edge0);
|
||||
if (nullptr == v1[K])
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
e1[K] = fsh.AllocateEdge(v1[0], Subdivide_CenterVertexSectorWeight(edge0, vertex0), v1[K], ON_SubDSectorType::IgnoredSectorWeight);
|
||||
if (nullptr == e1[K])
|
||||
if (e1[K].IsNull())
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
e1[K]->m_edge_tag = edge1_tag;
|
||||
e1[K].Edge()->m_edge_tag = edge1_tag;
|
||||
}
|
||||
|
||||
f1epts[K] = ON_SubDEdgePtr::Create(e1[K],1);
|
||||
if (3 == K)
|
||||
{
|
||||
// quads
|
||||
v1[2] = fsh.AllocateVertex(face0, subd_type, bUseSavedSubdivisionPoint, 2, 1 );
|
||||
e1[1] = fsh.AllocateEdge(v1[1], at_crease_weight, v1[2], ON_SubDSectorType::IgnoredSectorWeight);
|
||||
e1[2] = fsh.AllocateEdge(v1[2], ON_SubDSectorType::IgnoredSectorWeight, v1[3], at_crease_weight);
|
||||
f1epts[1] = ON_SubDEdgePtr::Create(e1[1],0);
|
||||
f1epts[2] = ON_SubDEdgePtr::Create(e1[2],0);
|
||||
if (nullptr == fsh.AllocateQuad(face0->m_zero_face_id, face0->m_id, f1epts) )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// tris
|
||||
e1[1] = fsh.AllocateEdge(v1[1], at_crease_weight, v1[2], at_crease_weight);
|
||||
f1epts[1] = ON_SubDEdgePtr::Create(e1[1],0);
|
||||
if (nullptr == fsh.AllocateTri(face0->m_zero_face_id, face0->m_id, f1epts) )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
}
|
||||
|
||||
f1epts[K] = e1[K].Reversed();
|
||||
|
||||
// quads
|
||||
v1[2] = fsh.AllocateSectorFaceVertex(face0 );
|
||||
e1[1] = fsh.AllocateEdge(v1[1], at_crease_weight, v1[2], ON_SubDSectorType::IgnoredSectorWeight);
|
||||
e1[2] = fsh.AllocateEdge(v1[2], ON_SubDSectorType::IgnoredSectorWeight, v1[3], at_crease_weight);
|
||||
f1epts[1] = e1[1];
|
||||
f1epts[2] = e1[2];
|
||||
if (nullptr == fsh.AllocateQuad(face0->m_zero_face_id, face0->m_id, f1epts) )
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
|
||||
if (i + 1 == N)
|
||||
{
|
||||
if (i + 1 == N && edge0_tag == edge1_tag)
|
||||
@@ -880,7 +640,7 @@ const ON_SubDVertex* ON_SubD::SubdivideSector(
|
||||
e1[0] = e1[K];
|
||||
f1epts[0] = f1epts[K].Reversed();
|
||||
v1[K] = nullptr;
|
||||
e1[K] = nullptr;
|
||||
e1[K] = ON_SubDEdgePtr::Null;
|
||||
}
|
||||
|
||||
return ON_SUBD_RETURN_ERROR(nullptr);
|
||||
@@ -888,8 +648,8 @@ const ON_SubDVertex* ON_SubD::SubdivideSector(
|
||||
|
||||
unsigned int ON_SubD::GetSectorComponentRing(
|
||||
const class ON_SubDSectorIterator& sit,
|
||||
size_t component_ring_capacity,
|
||||
ON_SubDComponentPtr* component_ring
|
||||
ON_SubDComponentPtr* component_ring,
|
||||
size_t component_ring_capacity
|
||||
)
|
||||
{
|
||||
if ( component_ring_capacity < 4 || nullptr == component_ring)
|
||||
@@ -952,6 +712,12 @@ unsigned int ON_SubD::GetSectorComponentRing(
|
||||
if (nullptr == face && ON_SubD::EdgeTag::Crease == edge0->m_edge_tag)
|
||||
return component_ring_count; // back to start dart case.
|
||||
}
|
||||
if (ON_SubD::VertexTag::Corner == center_vertex_tag)
|
||||
{
|
||||
// occurs in nonmanifold cases like the one in RH-49843
|
||||
if (nullptr == face && ON_SubD::EdgeTag::Crease == edge0->m_edge_tag)
|
||||
return component_ring_count; // back to start corner case.
|
||||
}
|
||||
}
|
||||
|
||||
return ON_SUBD_RETURN_ERROR(false); // damaged topology information
|
||||
@@ -994,7 +760,7 @@ unsigned int ON_SubD::GetSectorComponentRing(
|
||||
return ON_SUBD_RETURN_ERROR(0);
|
||||
|
||||
const unsigned int component_ring_capacity = 1 + vertex->m_edge_count + vertex->m_face_count;
|
||||
unsigned int component_ring_count = ON_SubD::GetSectorComponentRing(sit, component_ring_capacity, elements.Reserve(component_ring_capacity));
|
||||
unsigned int component_ring_count = ON_SubD::GetSectorComponentRing(sit, elements.Reserve(component_ring_capacity), component_ring_capacity);
|
||||
if (component_ring_count >= 4 && component_ring_count <= component_ring_capacity)
|
||||
elements.SetCount(component_ring_count);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user