diff --git a/opennurbs_3dm_settings.cpp b/opennurbs_3dm_settings.cpp
index 63413aba..4345c6c7 100644
--- a/opennurbs_3dm_settings.cpp
+++ b/opennurbs_3dm_settings.cpp
@@ -1003,8 +1003,6 @@ const ON_3dmRenderSettingsPrivate& ON_3dmRenderSettingsPrivate::operator = (cons
_sun ->OnInternalXmlChanged(p._sun );
_post_effects ->OnInternalXmlChanged(p._post_effects );
-#ifdef _DEBUG // See https://mcneel.myjetbrains.com/youtrack/issue/RH-77284
-
// Check that all the document objects now have matching properties.
ON_ASSERT(*_ground_plane == *p._ground_plane);
ON_ASSERT(*_dithering == *p._dithering);
@@ -1018,7 +1016,6 @@ const ON_3dmRenderSettingsPrivate& ON_3dmRenderSettingsPrivate::operator = (cons
// We can't check post effects because they may be different in terms of the _is_populated flag.
// After a lot of thinking, I simply cannot figure out how to solve this.
//_ASSERT(*_post_effects == *p._post_effects);
-#endif
}
return *this;
diff --git a/opennurbs_archive.cpp b/opennurbs_archive.cpp
index 373bd60b..093161a4 100644
--- a/opennurbs_archive.cpp
+++ b/opennurbs_archive.cpp
@@ -8959,19 +8959,6 @@ bool ON_BinaryArchive::BeginRead3dmTable( unsigned int typecode )
return false;
}
- const bool bIsTableTypeCode = (TCODE_TABLE == (0xFFFFF000 & tcode));
- if (false == bIsTableTypeCode)
- {
- // Dale Lear - Nov 8 2022 - ships in Rhino 8.2
- // Fix https://mcneel.myjetbrains.com/youtrack/issue/RH-77657
- // (detecting corruption in table headers prevents hangs).
- // This value isn't a table typecode (even from a table added int the future).
- // The file is badly corrupt at this point and we have to quit.
- ON_ERROR("tcode is not a table typecode. File is badly corrupted.");
- this->Internal_ReportCriticalError();
- return false;
- }
-
// A required table is not at the current position in the archive
// see if we can find it someplace else in the archive. This can
// happen when old code encounters a table that was added later.
diff --git a/opennurbs_brep.h b/opennurbs_brep.h
index 1cc081e1..3f180e66 100644
--- a/opennurbs_brep.h
+++ b/opennurbs_brep.h
@@ -1809,8 +1809,6 @@ public:
mesh_list - [out] meshes are appended to this array.
Returns:
Number of meshes appended to mesh_list[] array.
- Note:
- This function is not thread safe.
*/
int CreateMesh(
const ON_MeshParameters& mp,
diff --git a/opennurbs_color.cpp b/opennurbs_color.cpp
index 351fa690..5de13a69 100644
--- a/opennurbs_color.cpp
+++ b/opennurbs_color.cpp
@@ -310,60 +310,45 @@ void ON_Color::SetHSV(
double value // value
)
{
- if ( hue > ON_UNSET_FLOAT && hue < ON_UNSET_POSITIVE_FLOAT
- && saturation > ON_UNSET_FLOAT && saturation < ON_UNSET_POSITIVE_FLOAT
- && value > ON_UNSET_FLOAT && value < ON_UNSET_POSITIVE_FLOAT
- )
- {
- double r, g, b;
- if (value < 0.0)
- value = 0.0;
- else if (value > 1.0)
- value = 1.0;
- if (saturation <= 1.0 / 256.0)
- {
- r = value;
- g = value;
- b = value;
- }
- else
- {
- if (saturation > 1.0)
- saturation = 1.0;
- hue *= 3.0 / ON_PI; // (6.0 / 2.0 * ON_PI);
- int i = (int)floor(hue);
- if (i < 0 || i > 5) {
- hue = fmod(hue, 6.0);
- if (hue < 0.0)
- hue += 6.0;
- i = (int)floor(hue);
- }
- const double f = hue - i;
- const double p = value * (1.0 - saturation);
- const double q = value * (1.0 - (saturation * f));
- const double t = value * (1.0 - (saturation * (1.0 - f)));
- switch (i)
- {
- case 0:
- r = value; g = t; b = p; break;
- case 1:
- r = q; g = value; b = p; break;
- case 2:
- r = p; g = value; b = t; break;
- case 3:
- r = p; g = q; b = value; break;
- case 4:
- r = t; g = p; b = value; break;
- case 5:
- r = value; g = p; b = q; break;
- default:
- r = 0; g = 0; b = 0; break; // to keep lint quiet
- }
- }
- SetFractionalRGB(r, g, b);
+ int i;
+ double f, p, q, t, r, g, b;
+ if ( saturation <= 1.0/256.0 ) {
+ r = value;
+ g = value;
+ b = value;
}
- else
- *this = ON_Color::UnsetColor;
+ else {
+ hue *= 3.0 / ON_PI; // (6.0 / 2.0 * ON_PI);
+ i = (int)floor(hue);
+ if ( i < 0 || i > 5 ) {
+ hue = fmod(hue,6.0);
+ if ( hue < 0.0 )
+ hue += 6.0;
+ i = (int)floor(hue);
+ }
+ f = hue - i;
+ p = value * ( 1.0 - saturation);
+ q = value * ( 1.0 - ( saturation * f) );
+ t = value * ( 1.0 - ( saturation * ( 1.0 - f) ) );
+ switch( i)
+ {
+ case 0:
+ r = value; g = t; b = p; break;
+ case 1:
+ r = q; g = value; b = p; break;
+ case 2:
+ r = p; g = value; b = t; break;
+ case 3:
+ r = p; g = q; b = value; break;
+ case 4:
+ r = t; g = p; b = value; break;
+ case 5:
+ r = value; g = p; b = q; break;
+ default:
+ r = 0; g = 0; b = 0; break; // to keep lint quiet
+ }
+ }
+ SetFractionalRGB(r,g,b);
}
diff --git a/opennurbs_color.h b/opennurbs_color.h
index f759f1c8..16689447 100644
--- a/opennurbs_color.h
+++ b/opennurbs_color.h
@@ -260,9 +260,6 @@ public:
///
/// Specify a color using HSV (hue, saturation, value).
- /// If h, s or v are not in the open interval
- /// (ON_UNSET_FLOAT,ON_UNSET_POSITIVE_FLOAT),
- /// then this color is set to ON_Color::UnsetColor.
///
///
/// hue in radians
diff --git a/opennurbs_convex_poly.cpp b/opennurbs_convex_poly.cpp
index b3234c8d..6799a4f5 100644
--- a/opennurbs_convex_poly.cpp
+++ b/opennurbs_convex_poly.cpp
@@ -589,118 +589,7 @@ bool ON_ConvexPoly::Standardize(ON_4dex& dex, ON_4dPoint& B)
return rc;
}
-/**/
-void ON_ConvexHullRefEx::Initialize(const ON_3dVector* V0, int n)
-{
- m_n = n;
- m_dim = 3;
- m_v = *V0;
- m_is_rat = false;
- m_stride = 3;
-}
-
-void ON_ConvexHullRefEx::Initialize(const ON_4dPoint* V0, int n)
-{
- m_n = n;
- m_v = *V0;
- m_dim = 3;
- m_is_rat = true;
- m_stride = 4;
-}
-
-// style must be either not_rational or homogeneous_rational = 2,
-void ON_ConvexHullRefEx::Initialize(const double* V0, ON::point_style style, int count)
-{
- if (style == ON::homogeneous_rational)
- Initialize(reinterpret_cast(V0), count);
- else
- Initialize(reinterpret_cast(V0), count);
-}
-
-ON_ConvexHullRefEx::ON_ConvexHullRefEx(const ON_3dVector* V0, int n)
-{
- m_n = n;
- m_dim = 3;
- m_v = *V0;
- m_is_rat = false;
- m_stride = 3;
-}
-
-ON_ConvexHullRefEx::ON_ConvexHullRefEx(const ON_3dPoint* P0, int n)
-{
- m_n = n;
- m_dim = 3;
- m_v = *P0;
- m_is_rat = false;
- m_stride = 3;
-}
-
-ON_ConvexHullRefEx::ON_ConvexHullRefEx(const ON_4dPoint* V0, int n)
-{
- m_n = n;
- m_dim = 3;
- m_v = *V0;
- m_is_rat = true;
- m_stride = 4;
-}
-
-ON_ConvexHullRefEx::ON_ConvexHullRefEx(const double* V0, bool is_rat, int n, int dim)
-{
- m_n = n;
- m_dim = (dim>=0 && dim<4)?dim:0;
- m_v = V0;
- m_is_rat = is_rat;
- m_stride = is_rat ? dim+1 : dim;
-}
-
-ON_ConvexHullRefEx::ON_ConvexHullRefEx(const double* V0, bool is_rat, int n, int dim, int stride)
-{
- m_n = n;
- m_dim = (dim >= 0 && dim < 4) ? dim : 0;
- m_v = V0;
- m_is_rat = is_rat;
- m_stride = (stride>m_dim+is_rat)? stride: m_dim + is_rat;
-}
-
-ON_3dVector ON_ConvexHullRefEx::Vertex(int j) const
-{
- ON_3dVector v(0,0,0);
- for (int i = 0; i < m_dim; i++)
- v[i] = m_v[j * m_stride + i];
- if (m_is_rat )
- {
- double w = m_v[j * m_stride + m_dim];
- if (w)
- v *= (1.0 / w);
- }
-
- return v;
-}
-
-int ON_ConvexHullRefEx::SupportIndex(ON_3dVector W, int) const
-{
- int j0 = 0;
- double dot = Vertex(0) * W;
- for (int j = 1; j < m_n; j++)
- {
- ON_3dVector v = Vertex(j);
- double d = v * W;
- if (d > dot)
- {
- dot = d;
- j0 = j;
- }
- }
- return j0;
-}
-
-double ON_ConvexHullRefEx::MaximumCoordinate() const
-{
- return ON_MaximumCoordinate(m_v, m_dim, m_is_rat, m_n, m_stride);
-}
-
-/* ON_ConvexHullRef is DEEPRECATED because it doesn't work for 2d curves . Use ON_ConvexHellRefEx instead.*/
void ON_ConvexHullRef::Initialize(const ON_3dVector* V0, int n)
{
m_n = n;
@@ -824,7 +713,7 @@ double ON_ConvexHullPoint2::MaximumCoordinate() const
bool ON_ConvexPoly::GetClosestPointSeeded(ON_3dPoint P0,
ON_4dex& dex, ON_4dPoint& Bary, double atmost ) const
{
- ON_ConvexHullRefEx CvxPt(&P0, 1); // TODO don't use ON_ConvexHullRefEx
+ ON_ConvexHullRef CvxPt(&P0, 1);
// Set pdex to match the support of dex
ON_4dex pdex = dex;
for (int i = 0; i < 4; i++)
@@ -941,7 +830,7 @@ bool GJK_Simplex::Includes(int aind, int bind) // true if (aind, bind) is a vert
// Adex[i]<0 iff Bdex[i]<0 for all i
// Adex[i]>=0 for some i for some i
// By satisfying this condition Adex and Bdex will define a simplex in A - B
-// Note: As a result of a ClosestPoint calculation Adex and Bdex satisfy these conditions.
+// Note the result of a ClosestPoint calculation Adex and Bdex satisfy these conditions
bool ON_ConvexPoly::GetClosestPointSeeded(const ON_ConvexPoly& B,
ON_4dex& Adex, ON_4dex& Bdex, ON_4dPoint& Bary,
double atmost) const
diff --git a/opennurbs_convex_poly.h b/opennurbs_convex_poly.h
index 4916cefe..bb376619 100644
--- a/opennurbs_convex_poly.h
+++ b/opennurbs_convex_poly.h
@@ -337,50 +337,7 @@ Details:
// WARNING: Points are referenced not stored for optimal performance in'
// some applications.
// The list of points must remain alive and in there initial location
-// For the duration of this object.
-//
-// This is an improved version of ON_ConvexHullRef that includes support for 2d point lists.
-class ON_CLASS ON_ConvexHullRefEx : public ON_ConvexPoly
-{
-public:
- ON_ConvexHullRefEx() { m_n = 0; m_dim = 0; m_is_rat = false; m_stride = 3; };
- ON_ConvexHullRefEx(const ON_3dVector* V0, int count); // a 3d point array
- ON_ConvexHullRefEx(const ON_3dPoint* V0, int count); // a 3d point array
- ON_ConvexHullRefEx(const ON_4dPoint* V0, int count); // a array of homogeneous points
- ON_ConvexHullRefEx(const double* v0, bool is_rat, int n, int dim=3); // v0 is an array of 2d or 3d points in either euclidean or homogeneous coordinates. dim<4.
- ON_ConvexHullRefEx(const double* v0, bool is_rat, int n, int dim , int stride); // As above with a stride to the array. dim <4.
-
- void Initialize(const ON_3dVector* V0, int count);
- void Initialize(const ON_4dPoint* V0, int count);
- void Initialize(const double* V0, ON::point_style style, int count); // style must be either not_rational or homogeneous_rational = 2,
-
- int Count() const override { return m_n; }
- ON_3dVector Vertex(int j) const override;
-
- // Support map
- virtual int SupportIndex(ON_3dVector W, int i0) const override;
- virtual double MaximumCoordinate() const override;
-
- virtual ~ON_ConvexHullRefEx() override {};
-private:
-
- int m_n = 0;
- int m_dim = 3; // must be <4.
- bool m_is_rat = false;
- const double* m_v = nullptr;
- int m_stride = 3;
-};
-
-// 3d convex hull defined by an explicit collection of points called vertices.
-// Note: vertices need not be extreme points
-
-// WARNING: Points are referenced not stored for optimal performance in'
-// some applications.
-// The list of points must remain alive and in there initial location
-// For the duration of this object.
-//
-// GBA 02-Nov-23 This class is DEPRECATED and will be removed in the future.
-// Use ON_ConvexHullRefEx instead.
+// For the duration of this object.
class ON_CLASS ON_ConvexHullRef : public ON_ConvexPoly
{
public:
@@ -440,7 +397,7 @@ public:
};
private:
- ON_ConvexHullRefEx Ref;
+ ON_ConvexHullRef Ref;
ON_SimpleArray m_Vert;
};
diff --git a/opennurbs_embedded_file.cpp b/opennurbs_embedded_file.cpp
index 62b8d06d..34321343 100644
--- a/opennurbs_embedded_file.cpp
+++ b/opennurbs_embedded_file.cpp
@@ -38,7 +38,6 @@ public:
std::unique_ptr m_buffer;
size_t m_length = 0;
size_t m_compressed_length = 0;
- bool m_error = false;
};
bool LoadFile(const wchar_t* filename);
@@ -67,8 +66,6 @@ const ON_EmbeddedFile::CImpl::Data& ON_EmbeddedFile::CImpl::Data::operator = (co
m_length = m_compressed_length = 0;
}
- m_error = d.m_error;
-
return *this;
}
@@ -106,8 +103,6 @@ bool ON_EmbeddedFile::CImpl::LoadFile(const wchar_t* filename)
// Read the file data into the buffer.
const bool bOK = (ON_FileStream::Read(pFile, d.m_length, d.m_buffer.get()) == d.m_length);
- d.m_error = !bOK;
-
// Close the file.
ON_FileStream::Close(pFile);
@@ -116,9 +111,6 @@ bool ON_EmbeddedFile::CImpl::LoadFile(const wchar_t* filename)
bool ON_EmbeddedFile::CImpl::SaveFile(const wchar_t* filename) const
{
- if (m_data.m_error)
- return false; // Can't save when in error state.
-
if (0 == m_data.m_length)
return false; // Not loaded.
@@ -217,19 +209,14 @@ bool ON_EmbeddedFile::LoadFromBuffer(ON_Buffer& buf)
d.SetLength(size_t(buf.Size()));
// Load the buffer from 'buf'.
- if (buf.Read(d.m_length, d.m_buffer.get()) == d.m_length)
- return true;
+ if (buf.Read(d.m_length, d.m_buffer.get()) != d.m_length)
+ return false;
- m_impl->m_data.m_error = true;
-
- return false;
+ return true;
}
bool ON_EmbeddedFile::SaveToBuffer(ON_Buffer& buf) const
{
- if (m_impl->m_data.m_error)
- return false; // Can't save when in error state.
-
// Write the data to 'buf'.
buf.Write(m_impl->m_data.m_length, m_impl->m_data.m_buffer.get());
@@ -243,20 +230,14 @@ bool ON_EmbeddedFile::Read(ON_BinaryArchive& archive)
// Read the full file path of the original file.
ON_wString filename;
if (!archive.ReadString(filename))
- {
- m_impl->m_data.m_error = true;
return false;
- }
m_impl->m_orig_file = ON_FileSystemPath::CleanPath(filename);
// Read the original (uncompressed) size of the compressed buffer.
size_t uncompressed_size = 0;
if (!archive.ReadCompressedBufferSize(&uncompressed_size))
- {
- m_impl->m_data.m_error = true;
return false;
- }
// Allocate a buffer for the uncompressed data.
auto& d = m_impl->m_data;
@@ -268,10 +249,7 @@ bool ON_EmbeddedFile::Read(ON_BinaryArchive& archive)
const ON__UINT64 pos_before = archive.CurrentPosition();
if (!archive.ReadCompressedBuffer(uncompressed_size, d.m_buffer.get(), &bFailedCRC) && !bFailedCRC)
- {
- m_impl->m_data.m_error = true;
- return false;
- }
+ return false;
d.m_compressed_length = size_t(archive.CurrentPosition() - pos_before);
@@ -281,8 +259,6 @@ bool ON_EmbeddedFile::Read(ON_BinaryArchive& archive)
bool ON_EmbeddedFile::Write(ON_BinaryArchive& archive) const
{
auto& d = m_impl->m_data;
- if (d.m_error)
- return false; // Can't write when in error state.
// Write the original filename to the archive.
if (!archive.WriteString(m_impl->m_orig_file))
@@ -305,11 +281,6 @@ size_t ON_EmbeddedFile::CompressedLength(void) const
return m_impl->m_data.m_compressed_length;
}
-bool ON_EmbeddedFile::Error(void) const
-{
- return m_impl->m_data.m_error;
-}
-
bool ON_EmbeddedFile::Clear(void)
{
m_impl->m_orig_file.Empty();
@@ -317,8 +288,6 @@ bool ON_EmbeddedFile::Clear(void)
m_impl->m_data.SetLength(0);
m_impl->m_data.m_compressed_length = 0;
- m_impl->m_data.m_error = false;
-
return true;
}
diff --git a/opennurbs_embedded_file.h b/opennurbs_embedded_file.h
index c8056b82..ea979f7d 100644
--- a/opennurbs_embedded_file.h
+++ b/opennurbs_embedded_file.h
@@ -72,10 +72,6 @@ public:
// loaded by LoadFromFile() or LoadFromBuffer(), this method returns zero.
virtual size_t CompressedLength(void) const;
- // Returns true if the embedded file was loaded, but the load failed. This should only happen
- // if a buffer or archive being loaded is corrupted.
- bool Error(void) const;
-
// Clears the embedded file data. Returns true if successful, else false.
virtual bool Clear(void);
diff --git a/opennurbs_extensions.cpp b/opennurbs_extensions.cpp
index 21df559d..4bb9b215 100644
--- a/opennurbs_extensions.cpp
+++ b/opennurbs_extensions.cpp
@@ -2854,9 +2854,6 @@ bool ONX_Model::IncrementalReadFinish(
}
}
- if (0 != archive.CriticalErrorCount())
- return false;
-
// STEP 17: OPTIONAL - Read user tables as anonymous goo
// If you develop a plug-ins or application that uses OpenNURBS files,
// you can store anything you want in a user table.
@@ -2940,23 +2937,17 @@ bool ONX_Model::IncrementalReadFinish(
}
}
- if (0 != archive.CriticalErrorCount())
- return false;
-
// STEP 18: OPTIONAL - check for end mark
size_t file_length = 0;
- if (!archive.Read3dmEndMark(&file_length))
+ if ( !archive.Read3dmEndMark(&file_length) )
{
- if (archive.Archive3dmVersion() != 1)
+ if ( archive.Archive3dmVersion() != 1 )
{
// some v1 files are missing end-of-archive markers
}
}
else
- {
m_3dm_file_byte_count = file_length;
- }
-
return (0 == archive.CriticalErrorCount());
}
@@ -3020,11 +3011,8 @@ bool ONX_Model::Read(ON_BinaryArchive& archive, unsigned int table_filter,
ON_ModelComponentReference model_geometry_reference;
if (!IncrementalReadModelGeometry(archive, bManageComponents, bManageGeometry, bManageAttributes,
- model_object_type_filter, model_geometry_reference))
- {
- // Catastrophic error.
- break;
- }
+ model_object_type_filter, model_geometry_reference))
+ break; // Catastrophic error.
if (model_geometry_reference.IsEmpty())
break; // No more geometry.
@@ -5441,10 +5429,11 @@ bool ONX_ModelPrivate::GetEntireRDKDocument(const ONX_Model_UserData& docud, ON_
// Create an ON_EmbeddedFile object for each embedded file.
for (int i = 0; i < num_embedded_files; i++)
{
- // We keep the embedded file object even if it fails to load; then it will have an error flag set.
- // See ON_EmbeddedFile::Error().
ON_EmbeddedFile ef;
- ef.Read(archive);
+
+ if (!ef.Read(archive))
+ return false;
+
model->AddModelComponent(ef);
}
}
diff --git a/opennurbs_planesurface.cpp b/opennurbs_planesurface.cpp
index 12820578..eb8b18cd 100644
--- a/opennurbs_planesurface.cpp
+++ b/opennurbs_planesurface.cpp
@@ -991,74 +991,9 @@ bool ON_ClippingPlaneData::HasDefaultContent() const
return true;
}
-class ON_ClippingPlaneDataList
-{
-public:
- ON_ClippingPlaneDataList() = default;
- ~ON_ClippingPlaneDataList();
-
- ON_ClippingPlaneData* AppendNew();
- void DeleteEntry(unsigned int sn);
- ON_ClippingPlaneData* FromSerialNumber(unsigned int sn);
-private:
- ON_SimpleArray m_list;
-};
-
-static ON_ClippingPlaneDataList g_data_list;
+static ON_ClassArray g_data_list;
static ON_SleepLock g_data_list_lock;
-ON_ClippingPlaneDataList::~ON_ClippingPlaneDataList()
-{
- for(int i=0; im_sn == sn)
- {
- delete data;
- m_list.Remove(i);
- return;
- }
- }
-}
-
-ON_ClippingPlaneData* ON_ClippingPlaneDataList::AppendNew()
-{
- static unsigned int serial_number = 1;
- ON_ClippingPlaneData* data = new ON_ClippingPlaneData();
- m_list.Append(data);
- data->m_sn = serial_number++;
- return data;
-}
-
-ON_ClippingPlaneData* ON_ClippingPlaneDataList::FromSerialNumber(unsigned int sn)
-{
- if (0==sn)
- return nullptr;
-
- // TODO: use binary search
- int count = m_list.Count();
- for (int i=0; im_sn == sn)
- return data;
- }
- return nullptr;
-}
-
-/*
static int CompareClippingPlaneData(const ON_ClippingPlaneData* a, const ON_ClippingPlaneData* b)
{
if (a && b)
@@ -1075,16 +1010,25 @@ static int CompareClippingPlaneData(const ON_ClippingPlaneData* a, const ON_Clip
return 1;
return 0;
}
- */
+
+static int ClippingPlaneDataIndex(unsigned int serialNumber)
+{
+ if (0==serialNumber)
+ return -1;
+ ON_ClippingPlaneData data;
+ data.m_sn = serialNumber;
+ int index = g_data_list.BinarySearch(&data, CompareClippingPlaneData);
+ return index;
+}
static void DeleteClippingPlaneData(ON_ClippingPlaneDataStore& dataStore)
{
- const unsigned int serial_number = dataStore.m_sn;
- if (serial_number>0)
+ if (dataStore.m_sn>0)
{
bool bReturnLock = g_data_list_lock.GetLock();
+ int index = ClippingPlaneDataIndex(dataStore.m_sn);
dataStore.m_sn = 0;
- g_data_list.DeleteEntry(serial_number);
+ g_data_list.Remove(index);
if(bReturnLock)
g_data_list_lock.ReturnLock();
}
@@ -1096,7 +1040,8 @@ static ON_ClippingPlaneData* GetClippingPlaneData(unsigned int sn)
return nullptr;
bool bReturnLock = g_data_list_lock.GetLock();
- ON_ClippingPlaneData* rc = g_data_list.FromSerialNumber(sn);
+ int index = ClippingPlaneDataIndex(sn);
+ ON_ClippingPlaneData* rc = g_data_list.At(index);
if(bReturnLock)
g_data_list_lock.ReturnLock();
return rc;
@@ -1105,13 +1050,19 @@ static ON_ClippingPlaneData* GetClippingPlaneData(unsigned int sn)
static ON_ClippingPlaneData* GetClippingPlaneData(ON_ClippingPlaneDataStore& dataStore, bool createIfMissing)
{
bool bReturnLock = g_data_list_lock.GetLock();
-
- ON_ClippingPlaneData* rc = g_data_list.FromSerialNumber(dataStore.m_sn);
+ int index = ClippingPlaneDataIndex(dataStore.m_sn);
+ ON_ClippingPlaneData* rc = g_data_list.At(index);
if (nullptr==rc && createIfMissing)
{
- rc = g_data_list.AppendNew();
- if (rc)
- dataStore.m_sn = rc->m_sn;
+ unsigned int serial_number = 1;
+ const ON_ClippingPlaneData* last = g_data_list.Last();
+ if (last)
+ serial_number = last->m_sn + 1;
+
+ ON_ClippingPlaneData& data = g_data_list.AppendNew();
+ data.m_sn = serial_number;
+ dataStore.m_sn = data.m_sn;
+ rc = g_data_list.Last();
}
if(bReturnLock)
g_data_list_lock.ReturnLock();
diff --git a/opennurbs_planesurface.h b/opennurbs_planesurface.h
index aa0f0076..77de5bef 100644
--- a/opennurbs_planesurface.h
+++ b/opennurbs_planesurface.h
@@ -438,7 +438,7 @@ public:
domain.
Parameters:
dir - [in] 0 sets plane's x coordinate extents
- 1 sets plane's y coordinate extents
+ 0 sets plane's y coordinate extents
extents - [in] increasing interval
bSynchDomain - [in] if true, the corresponding evaluation interval
domain is set so that it matches the extents interval
@@ -458,7 +458,7 @@ public:
Gets the extents of the rectangle.
Parameters:
dir - [in] 0 gets plane's x coordinate extents
- 1 gets plane's y coordinate extents
+ 0 gets plane's y coordinate extents
Returns:
Increasing interval
See Also:
diff --git a/opennurbs_point.cpp b/opennurbs_point.cpp
index 88fc7350..9cf726a1 100644
--- a/opennurbs_point.cpp
+++ b/opennurbs_point.cpp
@@ -7871,31 +7871,25 @@ const ON_PlaneEquation operator*(const ON_Xform& xform, const ON_PlaneEquation&
// Find the maximum absolute value of a array of (possibly homogeneous) points
double ON_MaximumCoordinate(const double* data, int dim, bool is_rat, int count)
-{
- return ON_MaximumCoordinate(data, dim, is_rat, count, dim + is_rat);
-}
-
-// Find the maximum absolute value of an array with stride of (possibly homogeneous) points
-double ON_MaximumCoordinate(const double* data, int dim, bool is_rat, int count, int stride)
{
double norm = 0;
if (is_rat)
{
for (int i = 0; i < count; i++)
{
- double w = fabs(data[i*stride + dim ]);
+ double w = fabs(data[i*(dim+1) + dim ]);
double norm_i = 0;
for (int j = 0; j < dim; j++)
- norm_i = ON_Max(norm_i, fabs(data[i*stride + j]));
- if (norm_i > norm * w && w>0)
+ norm_i = ON_Max(norm_i, fabs(data[i*(dim+1) + j]));
+ if (norm_i > norm * w)
norm = norm_i / w;
}
}
else
{
- for (int i = 0; i < count; i++)
- for (int j=0; j=dim+is_rat
///////////////////////////////////////////////////////////////
//
diff --git a/opennurbs_public_version.h b/opennurbs_public_version.h
index 14c24d51..6f80424b 100644
--- a/opennurbs_public_version.h
+++ b/opennurbs_public_version.h
@@ -6,7 +6,7 @@
// To update version numbers, edit ..\build\build_dates.msbuild
#define RMA_VERSION_MAJOR 8
-#define RMA_VERSION_MINOR 2
+#define RMA_VERSION_MINOR 0
////////////////////////////////////////////////////////////////
//
@@ -14,10 +14,10 @@
// first step in each build.
//
#define RMA_VERSION_YEAR 2023
-#define RMA_VERSION_MONTH 11
-#define RMA_VERSION_DATE 15
-#define RMA_VERSION_HOUR 13
-#define RMA_VERSION_MINUTE 0
+#define RMA_VERSION_MONTH 8
+#define RMA_VERSION_DATE 22
+#define RMA_VERSION_HOUR 12
+#define RMA_VERSION_MINUTE 13
////////////////////////////////////////////////////////////////
//
@@ -35,8 +35,8 @@
// 3 = build system release build
#define RMA_VERSION_BRANCH 0
-#define VERSION_WITH_COMMAS 8,2,23319,13000
-#define VERSION_WITH_PERIODS 8.2.23319.13000
+#define VERSION_WITH_COMMAS 8,0,23234,12130
+#define VERSION_WITH_PERIODS 8.0.23234.12130
#define COPYRIGHT "Copyright (C) 1993-2023, Robert McNeel & Associates. All Rights Reserved."
#define SPECIAL_BUILD_DESCRIPTION "Public OpenNURBS C++ 3dm file IO library."
@@ -44,11 +44,11 @@
#define RMA_VERSION_NUMBER_MAJOR_WSTRING L"8"
#define RMA_PREVIOUS_VERSION_NUMBER_MAJOR_WSTRING L"7"
-#define RMA_VERSION_NUMBER_SR_STRING "SR2"
-#define RMA_VERSION_NUMBER_SR_WSTRING L"SR2"
+#define RMA_VERSION_NUMBER_SR_STRING "SR0"
+#define RMA_VERSION_NUMBER_SR_WSTRING L"SR0"
-#define RMA_VERSION_WITH_PERIODS_STRING "8.2.23319.13000"
-#define RMA_VERSION_WITH_PERIODS_WSTRING L"8.2.23319.13000"
+#define RMA_VERSION_WITH_PERIODS_STRING "8.0.23234.12130"
+#define RMA_VERSION_WITH_PERIODS_WSTRING L"8.0.23234.12130"
diff --git a/opennurbs_sha1.cpp b/opennurbs_sha1.cpp
index 3b9991e3..afe72cd6 100644
--- a/opennurbs_sha1.cpp
+++ b/opennurbs_sha1.cpp
@@ -23,17 +23,26 @@
ON_SHA1_Hash::ON_SHA1_Hash()
{
- memset(m_digest, 0, sizeof(m_digest));
+ ON__UINT32* p = (ON__UINT32*)m_digest;
+ p[0] = 0U;
+ p[1] = 0U;
+ p[2] = 0U;
+ p[3] = 0U;
+ p[4] = 0U;
}
bool operator==(const ON_SHA1_Hash& a, const ON_SHA1_Hash& b)
{
- return memcmp(a.m_digest, b.m_digest, sizeof(a.m_digest)) == 0;
+ const ON__UINT32* ai = (const ON__UINT32*)&a;
+ const ON__UINT32* bi = (const ON__UINT32*)&b;
+ return (ai[0] == bi[0] && ai[1] == bi[1] && ai[2] == bi[2] && ai[3] == bi[3] && ai[4] == bi[4]);
}
bool operator!=(const ON_SHA1_Hash& a, const ON_SHA1_Hash& b)
{
- return memcmp(a.m_digest, b.m_digest, sizeof(a.m_digest)) != 0;
+ const ON__UINT32* ai = (const ON__UINT32*)&a;
+ const ON__UINT32* bi = (const ON__UINT32*)&b;
+ return (ai[0] != bi[0] || ai[1] != bi[1] || ai[2] != bi[2] || ai[3] != bi[3] || ai[4] != bi[4]);
}
const ON_String ON_SHA1_Hash::ToUTF8String(
diff --git a/opennurbs_subd.cpp b/opennurbs_subd.cpp
index f39c8169..ab3a3eb0 100644
--- a/opennurbs_subd.cpp
+++ b/opennurbs_subd.cpp
@@ -8747,11 +8747,11 @@ unsigned int ON_SubD::DumpTopology(
if (false == text_log.IsTextHash())
{
- text_log.Print(L"Per vertex color settings:\n");
+ text_log.Print(L"Fragment per vertex color settings:\n");
{
ON_TextLogIndent indent1(text_log);
- text_log.Print(L"ColorsMappingTag() = ");
- const ON_MappingTag colors_tag = this->ColorsMappingTag();
+ text_log.Print(L"FragmentColorsMappingTag() = ");
+ const ON_MappingTag colors_tag = this->FragmentColorsMappingTag();
const ON_TextLog::LevelOfDetail lod = text_log.DecreaseLevelOfDetail();
colors_tag.Dump(text_log);
text_log.SetLevelOfDetail(lod);
@@ -10366,10 +10366,11 @@ unsigned int ON_SubDLevel::DumpTopology(
if (bNeedComma)
text_log.Print(", ");
else
- text_log.Print("Per face ");
+ text_log.Print("Per face");
bNeedComma = true;
- text_log.Print("color=");
- per_face_color.ToText(ON_Color::TextFormat::HashRGBa, 0, true, text_log);
+ text_log.Print("face color=(");
+ text_log.PrintColor(per_face_color);
+ text_log.Print(")");
}
const int per_face_material_channel_index = f->MaterialChannelIndex();
@@ -10378,9 +10379,9 @@ unsigned int ON_SubDLevel::DumpTopology(
if (bNeedComma)
text_log.Print(", ");
else
- text_log.Print("Per face ");
+ text_log.Print("Per face");
bNeedComma = true;
- text_log.Print("material channel index=%d", per_face_material_channel_index);
+ text_log.Print(" material channel index=%d", per_face_material_channel_index);
}
if (bNeedComma)
text_log.PrintNewLine();
@@ -10667,7 +10668,7 @@ size_t ON_SubD::SizeOfUnusedMeshFragments() const
//virtual
ON__UINT32 ON_SubD::DataCRC(ON__UINT32 current_remainder) const
{
- return this->GeometryHash().CRC32(current_remainder);
+ return 0;
}
//virtual
@@ -17428,39 +17429,27 @@ bool ON_SubD::CopyEvaluationCacheForExperts(const ON_SubD& src)
{
const ON_SubDimple* src_subdimple = src.m_subdimple_sp.get();
ON_SubDimple* this_subdimple = m_subdimple_sp.get();
- const bool bCopied
- = (nullptr != src_subdimple && nullptr != this_subdimple)
- ? this_subdimple->CopyEvaluationCacheForExperts(*src_subdimple)
- : false;
- if (bCopied)
- {
- if (this->HasFragmentTextureCoordinates())
- this_subdimple->Internal_SetFragmentTextureCoordinatesTextureSettingsHash(src_subdimple->FragmentColorsSettingsHash());
- if (this->HasFragmentColors())
- this_subdimple->Internal_SetFragmentColorsSettingsHash(src_subdimple->FragmentColorsSettingsHash());
- }
- return bCopied;
+ return (nullptr != src_subdimple && nullptr != this_subdimple) ? this_subdimple->CopyEvaluationCacheForExperts(*src_subdimple) : false;
}
bool ON_SubDimple::CopyEvaluationCacheForExperts(const ON_SubDimple& src)
{
const ON_SubDLevel* src_level = src.ActiveLevelConstPointer();
ON_SubDLevel* this_level = this->ActiveLevelPointer();
- unsigned fragment_status = 0u;
- const bool bCopied = (nullptr != src_level && nullptr != this_level) ? this_level->CopyEvaluationCacheForExperts(this->m_heap , *src_level, src.m_heap, fragment_status) : false;
- if (0 != (1u& fragment_status))
+ bool bFragmentsWereCopied = false;
+ const bool bCopied = (nullptr != src_level && nullptr != this_level) ? this_level->CopyEvaluationCacheForExperts(this->m_heap , *src_level, src.m_heap, bFragmentsWereCopied) : false;
+ if (bFragmentsWereCopied)
{
- if (2 != (1u & fragment_status))
- this->m_fragment_texture_settings_hash = src.m_fragment_texture_settings_hash;
- if (8 != (1u & fragment_status))
- this->m_fragment_colors_settings_hash = src.m_fragment_colors_settings_hash;
+ this->m_fragment_colors_mapping_tag = src.m_fragment_colors_mapping_tag;
+ this->m_fragment_texture_settings_hash = src.m_fragment_texture_settings_hash;
+ this->m_fragment_colors_settings_hash = src.m_fragment_colors_settings_hash;
}
return bCopied;
}
-bool ON_SubDLevel::CopyEvaluationCacheForExperts( ON_SubDHeap& this_heap, const ON_SubDLevel& src, const ON_SubDHeap& src_heap, unsigned& copy_status)
+bool ON_SubDLevel::CopyEvaluationCacheForExperts( ON_SubDHeap& this_heap, const ON_SubDLevel& src, const ON_SubDHeap& src_heap, bool& bFragmentsWereCopied)
{
- copy_status = 0u;
+ bFragmentsWereCopied = false;
// Validate conditions for coping the cached evaluation information
if (
this == &src
@@ -17724,17 +17713,8 @@ bool ON_SubDLevel::CopyEvaluationCacheForExperts( ON_SubDHeap& this_heap, const
this_face->SetSavedSubdivisionPoint(subdivision_point);
if (nullptr == this_face->MeshFragments() && nullptr != src_face->MeshFragments())
{
- const ON_SubDMeshFragment* this_frag = this_heap.CopyMeshFragments(src_face, subd_display_density, this_face);
- if (nullptr != this_frag)
- {
- copy_status |= 1u;
- if (this_frag->TextureCoordinateCount() > 0)
- copy_status |= 2u;
- if (this_frag->CurvatureCount() > 0)
- copy_status |= 4u;
- if (this_frag->ColorCount() > 0)
- copy_status |= 8u;
- }
+ if (nullptr != this_heap.CopyMeshFragments(src_face, subd_display_density, this_face))
+ bFragmentsWereCopied = true;
}
}
}
diff --git a/opennurbs_subd.h b/opennurbs_subd.h
index ba691f50..880a07a2 100644
--- a/opennurbs_subd.h
+++ b/opennurbs_subd.h
@@ -8171,69 +8171,6 @@ public:
*/
void ClearFragmentTextureCoordinatesTextureSettingsHash() const;
- ///
- /// Determing if this SubD's mesh fragments have per vertex texture coordinates.
- ///
- ///
- /// If this SubD has mesh fragments with per vertex texture coordinates, then true is returned.
- /// Otherwise false is returned.
- ///
- bool HasFragmentTextureCoordinates() const;
-
- ///
- /// This tag identifies the method and computation used to set the
- /// per vertex texture coordinates on the fragments. The tag is persistent so
- /// that the texture coordinates can be recomputed from the id in situations where
- /// fragments need to be recalculated.
- ///
- ///
- /// If this SubD has mesh fragments with per vertex texture coordinates and
- /// texture_mapping_tag = TextureMappingTag(), then true is returned.
- /// Otherwise false is returned.
- ///
- bool HasFragmentTextureCoordinates(
- ON_MappingTag texture_mapping_tag
- ) const;
-
- ///
- /// This hash uniquely identifies the method and computation used to
- /// set the per vertex texture coordinates on the fragments. The hash is a runtime
- /// value that has meaning only when fragments with per vertex texture coordinates
- /// exist.
- ///
- ///
- /// If this SubD has mesh fragments with per vertex texture coordinates and
- /// texture_settings_hash = TextureSettingsHash(), then true is returned.
- /// Otherwise false is returned.
- ///
- bool HasFragmentTextureCoordinates(
- ON_SHA1_Hash texture_settings_hash
- ) const;
-
- ///
- /// This hash uniquely identifies the method and computation used to
- /// set the per vertex texture coordinates on the fragments. The hash is a runtime
- /// value that has meaning only when fragments with per vertex texture coordinates
- /// exist.
- ///
- ///
- /// This tag identifies the method and computation used to set the
- /// per vertex texture coordinates on the fragments. The tag is persistent so
- /// that the texture coordinates can be recomputed from the id in situations where
- /// fragments need to be recalculated.
- ///
- ///
- /// If this SubD has mesh fragments with per vertex texture coordinates and
- /// texture_settings_hash = TextureSettingsHash() and
- /// texture_mapping_tag = TextureMappingTag(), then true is returned.
- /// Otherwise false is returned.
- ///
- bool HasFragmentTextureCoordinates(
- ON_SHA1_Hash texture_settings_hash,
- ON_MappingTag texture_mapping_tag
- ) const;
-
-
private:
/*
Description:
@@ -8310,27 +8247,17 @@ public:
///
bool HasFragmentColors() const;
- ///
- /// This tag identifies the method and computation used to set the
- /// per vertex colors on the fragments. The tag is persistent so
- /// that the colors can be recomputed from the id in situations where
- /// fragments need to be recalculated.
- ///
+ ///
///
/// If this SubD has mesh fragments with per vertex colors and
/// color_tag = FragmentColorsMappingTag(), then true is returned.
/// Otherwise false is returned.
///
bool HasFragmentColors(
- ON_MappingTag color_mapping_tag
+ ON_MappingTag color_tag
) const;
- ///
- /// This hash uniquely identifies the method and computation used to
- /// set the per vertex colors on the fragments. The has is a runtime
- /// value that has meaning only when fragments with per vertex colors
- /// exist.
- ///
+ ///
///
/// If this SubD has mesh fragments with per vertex colors and
/// color_settings_hash = FragmentColorsSettingsHash(), then true is returned.
@@ -8340,27 +8267,17 @@ public:
ON_SHA1_Hash color_settings_hash
) const;
- ///
- /// This hash uniquely identifies the method and computation used to
- /// set the per vertex colors on the fragments. The has is a runtime
- /// value that has meaning only when fragments with per vertex colors
- /// exist.
- ///
- ///
- /// This tag identifies the method and computation used to set the
- /// per vertex colors on the fragments. The tag is persistent so
- /// that the colors can be recomputed from the id in situations where
- /// fragments need to be recalculated.
- ///
+ ///
+ ///
///
/// If this SubD has mesh fragments with per vertex colors and
/// color_settings_hash = FragmentColorsSettingsHash() and
- /// color_mapping_tag = ColorsMappingTag(), then true is returned.
+ /// color_tag = FragmentColorsMappingTag(), then true is returned.
/// Otherwise false is returned.
///
bool HasFragmentColors(
ON_SHA1_Hash color_settings_hash,
- ON_MappingTag color_mapping_tag
+ ON_MappingTag color_tag
) const;
@@ -8376,39 +8293,33 @@ public:
bool bClearFragmentColorsMappingTag
);
-
- /*
- Returns:
- This mapping tag ideitifies the color mapping used to set fragment per vertex colors.
- */
- const ON_MappingTag ColorsMappingTag() const;
-
- /*
- Description:
- Set the colors mapping tag.
- Remarks:
- Calling this->SetColorsMappingTag() does not change existing cached
- fragment vertex colors. At an appropriate time, call this->SetFragmentColorsFromCallback()
- to update fragment vertex colors on any cached fragments.
-
- The color mapping tag and per vertex colors are mutable properties.
- They can be changed by rendering applications as needed.
- */
- void SetColorsMappingTag(const class ON_MappingTag&) const;
-
-
/*
Returns:
hash identifying the way the fragment vertex colors were set.
*/
const ON_SHA1_Hash FragmentColorsSettingsHash() const;
- ON_DEPRECATED_MSG("Use ON_SubD::ColorsMappingTag()")
+ /*
+ Returns:
+ The current fragment vertex colors mapping tag.
+ */
const ON_MappingTag FragmentColorsMappingTag() const;
- ON_DEPRECATED_MSG("Use ON_SubD::SetColorsMappingTag()")
+ /*
+ Description:
+ Set the fragment colors mapping tag.
+ Remarks:
+ Calling this->SetFragmentColorsMappingTag() does not change existing cached
+ fragment vertex colors. At an appropriate time, call this->SetFragmentColorsFromCallback()
+ to update fragment vertex colors on any cached fragments.
+
+ SubD fragment vertex tag and colors are a mutable property.
+ They can be changed by rendering applications as needed.
+ */
void SetFragmentColorsMappingTag(const class ON_MappingTag&) const;
+
+
public:
/*
Description:
@@ -8683,7 +8594,7 @@ public:
subd must point to an ON_SubD that was constructed on the heap using
an operator new call with a public ON_SubD constructor.
Returns:
- a pointer to the managed subd or nullptr subd if not valid.
+ a pointer to the managed subd or nullptr subd in not valid.
Example:
ON_SubD* subd = new ON_SubD(...);
ON_SubDRef subr;
@@ -10855,46 +10766,9 @@ public:
*/
ON_ComponentStatus Status() const;
- ///
- /// This simple version
- /// transforms the points and normals and unconditionally
- /// makes no changes to the curvatures, texture coordinates and colors.
- ///
- /// Typically lots of fragments are being transformed and
- /// the type and context of the transformation determines
- /// if texture coordinate, curvature and color inforation should be
- /// preserved or destroyed. It is better to determine the answers to these
- /// questions and call the version of Transform with
- /// the bKeepTextures, bKeepCurvatures and bKeepColors parameters.
- /// For example if the transformation is an isometry and the colors
- /// are set from the curvatures, then curvatures and colors should be
- /// kept. If the transformation is not an isometry, the curvatures should
- /// be destroyed.
- /// If the texture coordinates are set from grid location
- /// (fake surface paramaters), the the texture coordinates should be kept.
- /// If transform is not an identity and the texture coordinates come from a
- /// world object mapping, the should generally be destroyed.
- ///
- ///
- ///
bool Transform(
const ON_Xform& xform
- );
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- bool Transform(
- bool bKeepTextures,
- bool bKeepCurvatures,
- bool bKeepColors,
- const ON_Xform& xform
- );
+ );
ON_SubDMeshFragment* m_next_fragment;
ON_SubDMeshFragment* m_prev_fragment;
@@ -12637,7 +12511,7 @@ protected:
mutable double m_saved_subd_point1[3]; // saved subdivision point
private:
- // Reserved for future use for attributes that apply to all SubD components (ON_SubDVertex, ON_SubDEdge, and ON_SubDFace).
+ // Reserved for future use for attributes that apply to allSubD components (ON_SubDVertex, ON_SubDEdge, and ON_SubDFace).
ON__UINT64 m_reserved8bytes1;
ON__UINT64 m_reserved8bytes2;
ON__UINT64 m_reserved8bytes3;
@@ -12896,8 +12770,9 @@ public:
bTransformationSavedSubdivisionPoint - [in]
If the transformation is being applied to every vertex, edge and
face in every level of a subdivision object, and the transformation
- is an orientation preserving isometry (rotation, translation, ...),
- then set bTransformationSavedSubdivisionPoint = true to apply the
+ is an isometry (rotation, translation, ...), a uniform scale, or a
+ composition of these types, then set
+ bTransformationSavedSubdivisionPoint = true to apply the
transformation to saved subdivision and saved limit point information.
In all other cases, set bTransformationSavedSubdivisionPoint = false
and any saved subdivision points or saved limit points will be
@@ -13433,7 +13308,7 @@ public:
two attached edges are attached to one face,
the remaining edges are attached to two faces.
Returns:
- True if the vertex has boundary vertex toplology.
+ True if the vertex has interior vertex toplology.
Remarks:
Tags are ignored. This property is often used during construction
and modification when tags are not set.
@@ -13841,10 +13716,11 @@ public:
Parameters:
bTransformationSavedSubdivisionPoint - [in]
- If the transformation is being applied to every vertex, edge and
+ If the transformation is being applied to every vertex, edge and
face in every level of a subdivision object, and the transformation
- is an orientation preserving isometry (rotation, translation, ...),
- then set bTransformationSavedSubdivisionPoint = true to apply the
+ is an isometry (rotation, translation, ...), a uniform scale, or a
+ composition of these types, then set
+ bTransformationSavedSubdivisionPoint = true to apply the
transformation to saved subdivision and saved limit point information.
In all other cases, set bTransformationSavedSubdivisionPoint = false
and any saved subdivision points or saved limit points will be
@@ -14734,8 +14610,9 @@ public:
bTransformationSavedSubdivisionPoint - [in]
If the transformation is being applied to every vertex, edge and
face in every level of a subdivision object, and the transformation
- is an orientation preserving isometry (rotation, translation, ...),
- then set bTransformationSavedSubdivisionPoint = true to apply the
+ is an isometry (rotation, translation, ...), a uniform scale, or a
+ composition of these types, then set
+ bTransformationSavedSubdivisionPoint = true to apply the
transformation to saved subdivision and saved limit point information.
In all other cases, set bTransformationSavedSubdivisionPoint = false
and any saved subdivision points or saved limit points will be
@@ -15231,71 +15108,18 @@ public:
const class ON_SubDMeshFragment* MeshFragments() const;
- ///
- /// The face's control net center point is the average of the face's
- /// vertex control net points. This is the same point as the face's
- /// subdivision point.
- ///
- ///
- /// The average of the face's vertex control net points
- ///
const ON_3dPoint ControlNetCenterPoint() const;
- ///
- /// When the face's control net polygon is planar, the face's
- /// control net normal is a unit vector perpindicular to the plane
- /// that points outwards. If the control net polygon is not
- /// planar, the control net normal is control net normal is a unit
- /// vector that is the average of the control polygon's corner normals.
- ///
- ///
- /// A unit vector that is normal to planar control net polygons and a good
- /// compromise for nonplanar control net polygons.
- ///
const ON_3dVector ControlNetCenterNormal() const;
- ///
- /// The face's control net center frame is a plane
- /// with normal equal to this->ControlNetCenterNormal()
- /// and origin equal to this->ControlNetCenterPoint().
- /// The x and y axes of the frame have no predictable relationship
- /// to the face or SubD control net topology.
- ///
- ///
- /// A plane with unit normal equal to this->ControlNetCenterNormal()
- /// and origin equal to this->ControlNetCenterPoint().
- /// If the face is not valid, ON_Plane::NanPlane is returned.
- ///
const ON_Plane ControlNetCenterFrame() const;
- ///
- /// True if the control net polygon is convex with respect to the
- /// plane this->ControlNetCenterFrame().
- ///
bool IsConvex() const;
- ///
- /// True if the control net polygon is not convex with respect to the
- /// plane this->ControlNetCenterFrame().
- ///
bool IsNotConvex() const;
- ///
- /// Determine if the face's control net polygon is planar.
- ///
- ///
- ///
- /// True if the face's control net polygon is planar.
- ///
bool IsPlanar(double planar_tolerance = ON_ZERO_TOLERANCE) const;
- ///
- /// Determine if the face's control net polygon is not planar.
- ///
- ///
- ///
- /// True if the face's control net polygon is not planar.
- ///
bool IsNotPlanar(double planar_tolerance = ON_ZERO_TOLERANCE) const;
public:
@@ -17492,15 +17316,15 @@ public:
static const ON_SubDFromMeshParameters InteriorCreases;
// Create an interior sub-D crease along all input mesh double edges.
- // Look for convex corners at sub-D vertices with 2 edges or fewer
- // that have an included angle <= 120 degrees.
+ // Look for convex corners at sub-D vertices with 2 edges
+ // that have an included angle <= 90 degrees.
static const ON_SubDFromMeshParameters ConvexCornersAndInteriorCreases;
// Create an interior sub-D crease along all input mesh double edges.
- // Look for convex corners at sub-D vertices with 2 edges or fewer
- // that have an included angle <= 120 degrees.
- // Look for concave corners at sub-D vertices with 3 edges or more
- // that have an included angle >= 240 degrees.
+ // Look for convex corners at sub-D vertices with 2 edges
+ // that have an included angle <= 90 degrees.
+ // Look for concave corners at sub-D vertices with 3 edges
+ // that have an included angle >= 270 degrees.
static const ON_SubDFromMeshParameters ConvexAndConcaveCornersAndInteriorCreases;
///////////////////////////////////////////////////////////////////////////////////////
diff --git a/opennurbs_subd_copy.cpp b/opennurbs_subd_copy.cpp
index fc0b723e..b64f2943 100644
--- a/opennurbs_subd_copy.cpp
+++ b/opennurbs_subd_copy.cpp
@@ -866,13 +866,13 @@ ON_SubDimple::ON_SubDimple(const ON_SubDimple& src)
m_subd_appearance = src.m_subd_appearance;
m_texture_coordinate_type = src.m_texture_coordinate_type;
m_texture_mapping_tag = src.m_texture_mapping_tag;
- m_colors_mapping_tag = src.m_colors_mapping_tag;
// NOTE WELL: (Dale Lear Aug 2023)
- // Fragment settings like the two m_fragment_... values
+ // Fragment settings like the three m_fragment_... values
// should be copied only if the mesh fragments are copied
// and that happens conditionally and happens later
// if ON_SubDimple::CopyEvaluationCacheForExperts() is called.
+ // NO // m_fragment_colors_mapping_tag = src.m_fragment_colors_mapping_tag;
// NO // m_fragment_texture_settings_hash = src.m_fragment_texture_settings_hash;
// NO // m_fragment_colors_settings_hash = src.m_fragment_colors_settings_hash;
diff --git a/opennurbs_subd_data.cpp b/opennurbs_subd_data.cpp
index ba7eef62..784a0715 100644
--- a/opennurbs_subd_data.cpp
+++ b/opennurbs_subd_data.cpp
@@ -50,11 +50,9 @@ void ON_SubDimple::Clear()
m_subd_appearance = ON_SubD::DefaultSubDAppearance;
m_texture_coordinate_type = ON_SubDTextureCoordinateType::Unset;
m_texture_mapping_tag = ON_MappingTag::Unset;
- m_colors_mapping_tag = ON_MappingTag::Unset;
-
+ m_fragment_colors_mapping_tag = ON_MappingTag::Unset;
m_fragment_texture_settings_hash = ON_SHA1_Hash::EmptyContentHash;
m_fragment_colors_settings_hash = ON_SHA1_Hash::EmptyContentHash;
-
for (unsigned i = 0; i < m_levels.UnsignedCount(); ++i)
{
ON_SubDLevel* level = m_levels[i];
@@ -640,33 +638,27 @@ bool ON_SubDVertex::Transform(
{
TransformPoint(&xform.m_xform[0][0],m_P);
- if (bTransformationSavedSubdivisionPoint)
- {
- // Transform saved subdivision point
- Internal_TransformComponentBase(bTransformationSavedSubdivisionPoint, xform);
+ Internal_TransformComponentBase(bTransformationSavedSubdivisionPoint, xform);
- // NOTE WELL:
- // If the vertex
- // is tagged as ON_SubDVertexTag::Corner
- // and bTransformationSavedSubdivisionPoint is true,
- // and the corner sector(s) contains interior smooth edges,
- // and the transformation changes the angle between a corner sector's crease boundary,
- // then the sector's interior smooth edge's m_sector_coefficient[] could change
- // and invalidate the subdivison points and limit points.
- // This is only possible for uncommon (in practice) transformations
- // and corner sectors and will require a fair bit of testing for
- // now it's easier to simply set bTransformationSavedSubdivisionPoint to false
- // at a higher level when these types of transformations are encountered.
- if (bTransformationSavedSubdivisionPoint && Internal_SurfacePointFlag())
- {
- for (const ON_SubDSectorSurfacePoint* lp = &m_limit_point; nullptr != lp; lp = lp->m_next_sector_limit_point)
- const_cast(lp)->Transform(xform);
- }
- else
- Internal_ClearSurfacePointFlag();
+ // TODO:
+ // If the vertex
+ // is tagged as ON_SubDVertexTag::Corner
+ // and bTransformationSavedSubdivisionPoint is true,
+ // and the corner sector(s) contains interior smooth edges,
+ // and the transformation changes the angle between a corner sector's crease boundary,
+ // then the sector's interior smooth edge's m_sector_coefficient[] could change
+ // and invalidate the subdivison points and limit points.
+ // This is only possible for uncommon (in practice) transformations
+ // and corner sectors and will require a fair bit of testing for
+ // now it's easier to simply set bTransformationSavedSubdivisionPoint to false
+ // at a higher level when these types of transformations are encountered.
+ if ( bTransformationSavedSubdivisionPoint && Internal_SurfacePointFlag() )
+ {
+ for (const ON_SubDSectorSurfacePoint* lp = &m_limit_point; nullptr != lp; lp = lp->m_next_sector_limit_point)
+ const_cast(lp)->Transform(xform);
}
else
- this->ClearSavedSubdivisionPoints();
+ Internal_ClearSurfacePointFlag();
return true;
}
@@ -677,10 +669,6 @@ void ON_SubDVertex::UnsetControlNetPoint()
m_P[1] = ON_DBL_QNAN;
m_P[2] = ON_DBL_QNAN;
ClearSavedSubdivisionPoints();
- // With a nan control net point, there is no need for an expensive unset
- // of the neighborhod because the caller will either later pass
- // bClearNeighborhoodCache=true to ON_SubDVertex::SetControlNetPoint(...,bClearNeighborhoodCache)
- // or deal with cleaning up the cached evaluations in some other way.
}
bool ON_SubDVertex::SetControlNetPoint(
@@ -691,115 +679,54 @@ bool ON_SubDVertex::SetControlNetPoint(
if (false == control_net_point.IsValid())
return false;
- if (false == (m_P[0] == control_net_point.x && m_P[1] == control_net_point.y && m_P[2] == control_net_point.z))
+ if (!(m_P[0] == control_net_point.x && m_P[1] == control_net_point.y && m_P[2] == control_net_point.z))
{
m_P[0] = control_net_point.x;
m_P[1] = control_net_point.y;
m_P[2] = control_net_point.z;
ClearSavedSubdivisionPoints();
- for(;;)
+ if (bClearNeighborhoodCache)
{
- if (false == bClearNeighborhoodCache)
- break;
-
- if (this->m_edge_count <= 0 || nullptr == this->m_edges)
- break;
-
- // need to clear 2 rings of faces around "this" vertex.
-
- const bool bThisVertexIsACorner = ON_SubDVertexTag::Corner == this->m_vertex_tag;
- for (unsigned short vei = 0; vei < this->m_edge_count; vei++)
+ for (unsigned short vei = 0; vei < m_edge_count; vei++)
{
- const ON__UINT_PTR edgeptr = this->m_edges[vei].m_ptr;
- const ON_SubDEdge* edge = ON_SUBD_EDGE_POINTER(edgeptr);
+ ON_SubDEdge* edge = ON_SUBD_EDGE_POINTER(m_edges[vei].m_ptr);
if (nullptr == edge)
continue;
- edge->ON_SubDComponentBase::Internal_ClearSubdivisionPointAndSurfacePointFlags();
- // v1 = vertex opposite this on edge
- const ON_SubDVertex* v1 = edge->m_vertex[1 - ON_SUBD_EDGE_DIRECTION(edgeptr)];
- if (nullptr == v1)
- continue;
-
- v1->ClearSavedSubdivisionPoints();
-
- if (ON_SubDVertexTag::Smooth != v1->m_vertex_tag)
- continue;
- if (false == bThisVertexIsACorner)
- continue;
- if (false == edge->IsSmooth())
- continue;
- // When a corner vertex is moved, the sector coefficients
- // for smooth edges can change because the corner sector
- // coefficient depends on the angle between the creases that
- // bound the sector. For any other tag, the sector
- // coefficients depend only on the topology and tags and
- // moving a control net point does not change those.
- edge->UnsetSectorCoefficientsForExperts();
- }
-
- if (this->m_face_count <= 0 || nullptr == this->m_faces)
- break;
-
- //const ON_SubDFace* face = this->m_faces[m_face_count - 1];
- for(unsigned short vfi = 0; vfi < m_face_count; vfi++)
- {
- //const ON_SubDFace* prevface = face;
- const ON_SubDFace* face = this->m_faces[vfi];
- if (nullptr == face)
- continue;
-
- // face->ON_SubDComponentBase::Internal_ClearSubdivisionPointAndSurfacePointFlags() is fast
- face->ON_SubDComponentBase::Internal_ClearSubdivisionPointAndSurfacePointFlags();
-
- const ON_SubDEdgePtr* face_eptr = face->m_edge4;
- for (unsigned short fei = 0; fei < face->m_edge_count; fei++, face_eptr++)
+ edge->ClearSavedSubdivisionPoints();
+ ON_SubDFacePtr* fptr = edge->m_face2;
+ for (unsigned short efi = 0; efi < edge->m_face_count; efi++, fptr++)
{
- if (4 == fei)
+ if (2 == efi)
{
- face_eptr = face->m_edgex;
- if (nullptr == face_eptr)
- break;
+ fptr = edge->m_facex;
+ if (nullptr == fptr)
+ break;
}
- const ON__UINT_PTR e1ptr = face_eptr->m_ptr;
- ON_SubDEdge* e1 = ON_SUBD_EDGE_POINTER(e1ptr);
- if (nullptr == e1)
+ ON_SubDFace* face = ON_SUBD_FACE_POINTER(fptr->m_ptr);
+ if (nullptr == face)
continue;
+ face->ClearSavedSubdivisionPoints();
- // e1->ON_SubDComponentBase::Internal_ClearSubdivisionPointAndSurfacePointFlags() is fast.
- // There is no need to unset e1 sector coefficients.
- e1->ON_SubDComponentBase::Internal_ClearSubdivisionPointAndSurfacePointFlags();
- const ON_SubDVertex* v1 = e1->m_vertex[ON_SUBD_EDGE_DIRECTION(e1ptr)];
- if (this == v1 || nullptr == v1)
- continue;
- v1->ClearSavedSubdivisionPoints();
-
- if (v1->m_edge_count <= 0 || nullptr == v1->m_edges)
- continue;
- for (unsigned short v1ei = 0; v1ei < v1->m_edge_count; v1ei++)
+ ON_SubDEdgePtr* eptr = face->m_edge4;
+ for (unsigned short fei = 0; fei < face->m_edge_count; fei++, eptr++)
{
- // e2 is sometime in ring 1, sometimes between ring 1 and 2,
- // and sometimes in ring 2, but this is enough to clear the
- // ring 2 edges that can be modified by moving "this" vertex.
- const ON_SubDEdge* e2 = ON_SUBD_EDGE_POINTER(v1->m_edges[v1ei].m_ptr);
- if (nullptr != e2)
- e2->ON_SubDComponentBase::Internal_ClearSubdivisionPointAndSurfacePointFlags();
- }
-
- if (v1->m_face_count <= 0 || nullptr == v1->m_faces)
- continue;
- for (unsigned short v1fi = 0; v1fi < v1->m_face_count; v1fi++)
- {
- // f2 is sometimes in ring 1 and sometimes in ring 2, but this
- // is enough to clear the ring 2 faces that can be modified by
- // moving "this" vertex.
- const ON_SubDFace* f2 = v1->m_faces[v1fi];
- if (nullptr != f2)
- f2->ON_SubDComponentBase::Internal_ClearSubdivisionPointAndSurfacePointFlags();
+ if (4 == fei)
+ {
+ eptr = face->m_edgex;
+ if (nullptr == eptr)
+ break;
+ }
+ ON_SubDEdge* fedge = ON_SUBD_EDGE_POINTER(eptr->m_ptr);
+ if (nullptr == fedge)
+ continue;
+ ON_SubDVertex* fvertex = const_cast(fedge->m_vertex[ON_SUBD_EDGE_DIRECTION(eptr->m_ptr)]);
+ if (nullptr == fvertex)
+ continue;
+ fvertex->ClearSavedSubdivisionPoints();
}
}
}
- break;
}
}
@@ -837,27 +764,15 @@ bool ON_SubDFace::Transform(
const class ON_Xform& xform
)
{
- if (bTransformationSavedSubdivisionPoint)
- {
- Internal_TransformComponentBase(true, xform);
+ Internal_TransformComponentBase(bTransformationSavedSubdivisionPoint, xform);
- if (Internal_SurfacePointFlag())
- {
- // bTransformationSavedSubdivisionPoint = true means xform is an isometry.
- // If its more complicated than this, the calling code should
- // reset or addjut colors as needed based on information in the
- // SubD's texture coordinate mapping tag and color mapping tag.
- // Note that both of those tags have their transformation updated
- // so intelligent decisions can be made at a higher level where
- // there is enough context to make the correct decision.
- for (ON_SubDMeshFragment* f = m_mesh_fragments; nullptr != f; f = f->m_next_fragment)
- f->Transform(true, true, true, xform);
- }
- else
- Internal_ClearSurfacePointFlag();
+ if (bTransformationSavedSubdivisionPoint && Internal_SurfacePointFlag() )
+ {
+ for (ON_SubDMeshFragment* f = m_mesh_fragments; nullptr != f; f = f->m_next_fragment)
+ f->Transform(xform);
}
else
- this->ClearSavedSubdivisionPoints();
+ Internal_ClearSurfacePointFlag();
return true;
}
@@ -956,10 +871,7 @@ bool ON_SubDimple::Transform(
// In all other cases, set bTransformationSavedSubdivisionPoint = false
// and any saved subdivision points or saved limit points will be
// deleted.
- const bool bTransformationSavedSubdivisionPoint = (1 == xform.IsRigid());
-
- bool bHasTextures = false;
- bool bHasColors = false;
+ const bool bTransformationSavedSubdivisionPoint = false; // todo - set this correctly
for (unsigned int level_index = 0; level_index < level_count; level_index++)
{
@@ -975,25 +887,8 @@ bool ON_SubDimple::Transform(
rc = false;
break;
}
-
- if (level->m_face_count > 0 && level->m_face)
- {
- const ON_SubDMeshFragment* frag = level->m_face[0]->MeshFragments();
- if (nullptr != frag)
- {
- if (frag->TextureCoordinateCount() > 0)
- bHasTextures = true;
- if (frag->ColorCount() > 0)
- bHasColors = true;
- }
- }
}
- if (bHasTextures)
- this->m_texture_mapping_tag.Transform(xform);
- if (bHasColors)
- this->m_colors_mapping_tag.Transform(xform);
-
// SubD has been moved - geometry changed and we need to bump the geometry content serial number.
this->ChangeGeometryContentSerialNumber(false);
@@ -1056,17 +951,7 @@ bool ON_SubDimple::Transform(
bool ON_SubDMeshFragment::Transform(
const ON_Xform& xform
-)
-{
- return this->Transform(true, true, true, xform);
-}
-
-bool ON_SubDMeshFragment::Transform(
- bool bKeepCurvatures,
- bool bKeepTextureCoordinates,
- bool bKeepColors,
- const ON_Xform& xform
-)
+ )
{
const unsigned count = PointCount();
if (0 == count)
@@ -1111,31 +996,6 @@ bool ON_SubDMeshFragment::Transform(
}
}
ON_GetPointListBoundingBox(3,0,count,(int)m_P_stride,m_P,&m_surface_bbox.m_min.x,&m_surface_bbox.m_max.x,false);
-
- if (false == bKeepTextureCoordinates)
- {
- this->SetTextureCoordinatesExistForExperts(false);
- double* p = &this->m_ctrlnetT[0][0];
- double* p1 = p + sizeof(this->m_ctrlnetT) / sizeof(this->m_ctrlnetT[0][0]);
- while (p < p1)
- *p++ = ON_DBL_QNAN;
- }
- if (false == bKeepCurvatures)
- {
- this->SetCurvaturesExistForExperts(false);
- this->m_ctrlnetK[0] = ON_SurfaceCurvature::Nan;
- this->m_ctrlnetK[1] = ON_SurfaceCurvature::Nan;
- this->m_ctrlnetK[2] = ON_SurfaceCurvature::Nan;
- this->m_ctrlnetK[3] = ON_SurfaceCurvature::Nan;
- }
- if (false == bKeepColors)
- {
- this->SetColorsExistForExperts(false);
- this->m_ctrlnetC[0] = ON_Color::UnsetColor;
- this->m_ctrlnetC[1] = ON_Color::UnsetColor;
- this->m_ctrlnetC[2] = ON_Color::UnsetColor;
- this->m_ctrlnetC[3] = ON_Color::UnsetColor;
- }
return true;
}
@@ -1143,12 +1003,11 @@ bool ON_SubDMeshImpl::Transform(
const ON_Xform& xform
)
{
- const bool bIsometry = (1 == xform.IsRigid());
m_bbox = ON_BoundingBox::EmptyBoundingBox;
ON_BoundingBox bbox = ON_BoundingBox::EmptyBoundingBox;
for ( const ON_SubDMeshFragment* fragment = m_first_fragment; nullptr != fragment; fragment = fragment->m_next_fragment)
{
- if ( false == const_cast(fragment)->Transform(bIsometry, bIsometry, bIsometry, xform) )
+ if ( false == const_cast(fragment)->Transform(xform) )
return ON_SUBD_RETURN_ERROR(false);
if ( fragment == m_first_fragment )
bbox = fragment->m_surface_bbox;
diff --git a/opennurbs_subd_data.h b/opennurbs_subd_data.h
index a289d39d..daf85149 100644
--- a/opennurbs_subd_data.h
+++ b/opennurbs_subd_data.h
@@ -1160,24 +1160,11 @@ public:
void ClearEvaluationCache() const;
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// If (0 != 1(&)copy_status, then fragments were copied.
- /// If (0 != 2(&)copy_status, then fragment per vertex texture coordinates were copied.
- /// If (0 != 4(&)copy_status, then fragment per vertex principal curvatures were copied.
- /// If (0 != 8(&)copy_status, then fragment per vertex colors were copied.
- ///
- ///
bool CopyEvaluationCacheForExperts(
class ON_SubDHeap& this_heap,
const ON_SubDLevel& src,
const class ON_SubDHeap& src_heap,
- unsigned& copy_status
+ bool& bFragmentsWereCopied
);
void ClearTopologicalAttributes() const
@@ -2504,33 +2491,21 @@ public:
m_fragment_colors_settings_hash = hash;
}
- const ON_MappingTag ColorsMappingTag() const;
- void SetColorsMappingTag(const ON_MappingTag& mapping_tag) const;
+ const ON_MappingTag FragmentColorsMappingTag() const;
+ void SetFragmentColorsMappingTag(const ON_MappingTag& mapping_tag) const;
private:
mutable ON_SubDComponentLocation m_subd_appearance = ON_SubD::DefaultSubDAppearance;
mutable ON_SubDTextureCoordinateType m_texture_coordinate_type = ON_SubDTextureCoordinateType::Unset;
unsigned short m_reserved = 0;
-
- // m_texture_mapping_tag identifies the mapping used to set the fragment per vertex texture coordinates.
- // If m_texture_mapping_tag is set and fragment per vertex texture coordinates are missing,
- // m_texture_mapping_tag.m_mapping_id specifies the method used to update the texture coordinates.
mutable ON_MappingTag m_texture_mapping_tag;
+ mutable ON_MappingTag m_fragment_colors_mapping_tag;
- // m_colors_mapping_tag identifies the mapping used to set the fragment per vertex colors.
- // If m_colors_mapping_tag is set and fragment per vertex colors are missing,
- // m_colors_mapping_tag.m_mapping_id specifies the method used to update the colors.
- // Per vertex colors are used for false color analysis modes (curvature, draft angle) and
- // other specific uses.
- mutable ON_MappingTag m_colors_mapping_tag;
-
- // hash of the settings used to create the current fragment texture coordinates.
- // This hash has meaning only when fragments with per vertex texture coordinates exist.
+ // hash of the settings used to create the current fragment texture coordinates
mutable ON_SHA1_Hash m_fragment_texture_settings_hash = ON_SHA1_Hash::EmptyContentHash;
// hash of the settings used to create the current fragment vertex colors
- // This hash has meaning only when fragments with per vertex colors exist.
mutable ON_SHA1_Hash m_fragment_colors_settings_hash = ON_SHA1_Hash::EmptyContentHash;
ON_SimpleArray< ON_SubDLevel* > m_levels;
diff --git a/opennurbs_subd_eval.cpp b/opennurbs_subd_eval.cpp
index 04de3cf7..3d43aa93 100644
--- a/opennurbs_subd_eval.cpp
+++ b/opennurbs_subd_eval.cpp
@@ -1089,6 +1089,7 @@ bool ON_SubDVertex::SurfacePointIsSet() const
void ON_SubDEdge::ClearSavedSubdivisionPoints() const
{
+ // considering using a global pool for the limit curve cache - not yet.
ON_SubDComponentBase::Internal_ClearSubdivisionPointAndSurfacePointFlags();
}
diff --git a/opennurbs_subd_fragment.cpp b/opennurbs_subd_fragment.cpp
index ba788e39..6eb9f2fd 100644
--- a/opennurbs_subd_fragment.cpp
+++ b/opennurbs_subd_fragment.cpp
@@ -635,19 +635,11 @@ bool ON_SubD::SetFragmentColorsFromCallback(
const ON_SurfaceCurvature& K)
) const
{
- if (bLazySet
+ if (bLazySet
&& fragment_colors_settings_hash == FragmentColorsSettingsHash()
- && fragment_colors_mapping_tag == ColorsMappingTag()
- && this->HasFragmentColors()
+ && fragment_colors_mapping_tag == FragmentColorsMappingTag()
)
- {
- // This subd has fragments with per vertex colors.
- // The settings used to create those colors exactly
- // match the settings that color_callback() will use
- // to assign colors. The caller said to be lazy, so
- // assume the existing colors are correct and return.
return true;
- }
bool bFragmentVetexColorsSet = false;
const ON_SubDimple* subdimple = this->SubDimple();
@@ -673,13 +665,13 @@ bool ON_SubD::SetFragmentColorsFromCallback(
if (bFragmentVetexColorsSet)
{
subdimple->Internal_SetFragmentColorsSettingsHash(fragment_colors_settings_hash);
- SetColorsMappingTag(fragment_colors_mapping_tag);
+ SetFragmentColorsMappingTag(fragment_colors_mapping_tag);
ChangeRenderContentSerialNumber();
}
else
{
subdimple->Internal_SetFragmentColorsSettingsHash(ON_SHA1_Hash::EmptyContentHash);
- this->SetColorsMappingTag(ON_MappingTag::Unset);
+ this->SetFragmentColorsMappingTag(ON_MappingTag::Unset);
}
}
@@ -687,58 +679,6 @@ bool ON_SubD::SetFragmentColorsFromCallback(
}
bool ON_SubD::HasFragmentColors() const
-{
- bool bHasColors = false;
- const ON_SubDimple* subdimple = this->SubDimple();
- if (nullptr != subdimple)
- {
- ON_SubDMeshFragmentIterator fragit(*this);
- for (const ON_SubDMeshFragment* frag = fragit.FirstFragment(); nullptr != frag; frag = fragit.NextFragment())
- {
- if (0 == frag->ColorCount())
- return false;
- // NOTE WELL:
- // All fragments need to be tested as lasy updates of the
- // surface mesh cache result in the update fragments having
- // no colors while the preexisting fragments have colors.
- bHasColors = true; // fragments with colors exist
- }
- }
- return bHasColors;
-}
-
-bool ON_SubD::HasFragmentColors(
- ON_MappingTag color_mapping_tag
-) const
-{
- return
- this->ColorsMappingTag() == color_mapping_tag
- && this->HasFragmentColors();
-}
-
-bool ON_SubD::HasFragmentColors(
- ON_SHA1_Hash color_settings_hash
-) const
-{
- return
- this->FragmentColorsSettingsHash() == color_settings_hash
- && this->HasFragmentColors();
-}
-
-bool ON_SubD::HasFragmentColors(
- ON_SHA1_Hash color_settings_hash,
- ON_MappingTag color_mapping_tag
-) const
-{
- return
- this->FragmentColorsSettingsHash() == color_settings_hash
- && this->ColorsMappingTag() == color_mapping_tag
- && this->HasFragmentColors();
-}
-
-
-
-bool ON_SubD::HasFragmentTextureCoordinates() const
{
const ON_SubDimple* subdimple = this->SubDimple();
if (nullptr != subdimple)
@@ -753,37 +693,36 @@ bool ON_SubD::HasFragmentTextureCoordinates() const
return false;
}
-bool ON_SubD::HasFragmentTextureCoordinates(
- ON_MappingTag texture_mapping_tag
+bool ON_SubD::HasFragmentColors(
+ ON_MappingTag color_tag
) const
{
return
- this->TextureMappingTag(true) == texture_mapping_tag
- && this->HasFragmentTextureCoordinates();
+ this->FragmentColorsMappingTag() == color_tag
+ && this->HasFragmentColors();
}
-bool ON_SubD::HasFragmentTextureCoordinates(
- ON_SHA1_Hash texture_settings_hash
+bool ON_SubD::HasFragmentColors(
+ ON_SHA1_Hash color_settings_hash
) const
{
return
- this->TextureSettingsHash() == texture_settings_hash
- && this->HasFragmentTextureCoordinates();
+ this->FragmentColorsSettingsHash() == color_settings_hash
+ && this->HasFragmentColors();
}
-bool ON_SubD::HasFragmentTextureCoordinates(
- ON_SHA1_Hash texture_settings_hash,
- ON_MappingTag texture_mapping_tag
+bool ON_SubD::HasFragmentColors(
+ ON_SHA1_Hash color_settings_hash,
+ ON_MappingTag color_tag
) const
{
return
- this->TextureSettingsHash() == texture_settings_hash
- && this->TextureMappingTag(true) == texture_mapping_tag
- && this->HasFragmentTextureCoordinates();
+ this->FragmentColorsSettingsHash() == color_settings_hash
+ && this->FragmentColorsMappingTag() == color_tag
+ && this->HasFragmentColors();
}
-
void ON_SubD::ClearFragmentColors(
bool bClearFragmentColorsMappingTag
)
@@ -802,7 +741,7 @@ void ON_SubD::ClearFragmentColors(
if (bClearFragmentColorsMappingTag)
{
subdimple->Internal_SetFragmentColorsSettingsHash(ON_SHA1_Hash::EmptyContentHash);
- this->SetColorsMappingTag(ON_MappingTag::Unset);
+ this->SetFragmentColorsMappingTag(ON_MappingTag::Unset);
}
if (bFragmentsChanged)
this->ChangeRenderContentSerialNumber();
@@ -816,26 +755,16 @@ const ON_SHA1_Hash ON_SubD::FragmentColorsSettingsHash() const
}
void ON_SubD::SetFragmentColorsMappingTag(const ON_MappingTag& colors_mapping_tag) const
-{
- return SetColorsMappingTag(colors_mapping_tag);
-}
-
-void ON_SubD::SetColorsMappingTag(const ON_MappingTag& colors_mapping_tag) const
{
const ON_SubDimple* dimple = SubDimple();
if (nullptr != dimple)
- dimple->SetColorsMappingTag(colors_mapping_tag);
+ dimple->SetFragmentColorsMappingTag(colors_mapping_tag);
}
const ON_MappingTag ON_SubD::FragmentColorsMappingTag() const
-{
- return ColorsMappingTag();
-}
-
-const ON_MappingTag ON_SubD::ColorsMappingTag() const
{
const ON_SubDimple* dimple = SubDimple();
- return (nullptr != dimple) ? dimple->ColorsMappingTag() : ON_MappingTag::Unset;
+ return (nullptr != dimple) ? dimple->FragmentColorsMappingTag() : ON_MappingTag::Unset;
}
const ON_3dPoint ON_SubDMeshFragment::ControlNetQuadPoint(
diff --git a/opennurbs_subd_texture.cpp b/opennurbs_subd_texture.cpp
index 46ec7b8c..40100857 100644
--- a/opennurbs_subd_texture.cpp
+++ b/opennurbs_subd_texture.cpp
@@ -256,16 +256,16 @@ const ON_MappingTag ON_SubDimple::TextureMappingTag(bool bIgnoreTextureCoordinat
#pragma endregion
#endif
-const ON_MappingTag ON_SubDimple::ColorsMappingTag() const
+const ON_MappingTag ON_SubDimple::FragmentColorsMappingTag() const
{
- return m_colors_mapping_tag;
+ return m_fragment_colors_mapping_tag;
}
-void ON_SubDimple::SetColorsMappingTag(const ON_MappingTag& mapping_tag) const
+void ON_SubDimple::SetFragmentColorsMappingTag(const ON_MappingTag& mapping_tag) const
{
- if (0 != ON_MappingTag::CompareAll(this->m_colors_mapping_tag, mapping_tag))
+ if (0 != ON_MappingTag::CompareAll(this->m_fragment_colors_mapping_tag, mapping_tag))
{
- this->m_colors_mapping_tag = mapping_tag;
+ this->m_fragment_colors_mapping_tag = mapping_tag;
ChangeRenderContentSerialNumber();
}
}
diff --git a/opennurbs_text.cpp b/opennurbs_text.cpp
index dd5d6291..697ec81b 100644
--- a/opennurbs_text.cpp
+++ b/opennurbs_text.cpp
@@ -1133,15 +1133,19 @@ int ON_TextContent::Dimension() const
const ON_BoundingBox ON_TextContent::TextContentBoundingBox() const
{
ON_TextRunArray* runs = const_cast(this)->TextRuns(false);
- const int run_count = (nullptr != runs) ? runs->Count() : 0;
+ const int run_count
+ = (nullptr != runs)
+ ? runs->Count()
+ : 0;
- // 28 Aug 2023 S. Baer
- // Computing a content hash takes longer than just computing the bounding box
- // for simple single run situations. Only use the cached bbox when there are
- // more than one run.
- if ( run_count > 1 &&
- m_text_content_bbox.IsValid() &&
- m_text_content_bbox_hash == TextContentHash())
+ if (run_count <= 0)
+ return ON_BoundingBox::EmptyBoundingBox;
+
+ const ON_SHA1_Hash text_content_hash = TextContentHash();
+ if (
+ m_text_content_bbox.IsValid()
+ && m_text_content_bbox_hash == text_content_hash
+ )
{
return m_text_content_bbox;
}
@@ -1158,8 +1162,8 @@ const ON_BoundingBox ON_TextContent::TextContentBoundingBox() const
if (nullptr == run)
continue;
- if (ON_TextRun::RunType::kText == run->Type() ||
- ON_TextRun::RunType::kField == run->Type())
+ if (ON_TextRun::RunType::kText == (*runs)[i]->Type() ||
+ ON_TextRun::RunType::kField == (*runs)[i]->Type())
{
ON_BoundingBox runbox = run->BoundingBox();
if (false == runbox.IsValid())
@@ -1200,10 +1204,10 @@ const ON_BoundingBox ON_TextContent::TextContentBoundingBox() const
bbox.m_min.z = 0.0;
bbox.m_max.z = 0.0;
- if (run_count>1 && bbox.IsValid())
+ if (bbox.IsValid())
{
m_text_content_bbox = bbox;
- m_text_content_bbox_hash = TextContentHash();
+ m_text_content_bbox_hash = text_content_hash;
}
return bbox;
diff --git a/opennurbs_viewport.cpp b/opennurbs_viewport.cpp
index 9c140f5c..3a7ad8be 100644
--- a/opennurbs_viewport.cpp
+++ b/opennurbs_viewport.cpp
@@ -4964,8 +4964,8 @@ void ON_Viewport::GetPerspectiveClippingPlaneConstraints(
if ( depth_buffer_bit_depth >= 32 )
{
- nof = 0.0005; // Changed to match 24 bit defaults: https://mcneel.myjetbrains.com/youtrack/issue/RH-77623
- n = 0.005; // Do not change back unless you've fixed the problems shown in the YT somewhere else.
+ nof = 0.0001;
+ n = 0.001;
}
else if ( depth_buffer_bit_depth >= 24 )
{
diff --git a/opennurbs_xform.h b/opennurbs_xform.h
index ef9cf9d3..d6fcd341 100644
--- a/opennurbs_xform.h
+++ b/opennurbs_xform.h
@@ -277,41 +277,23 @@ public:
/*
Description:
- NOTE: A better name for this fuction would be IsIsometry().
-
- An "isometry" transformation is an affine transformation that preserves
- distances. Isometries include transformation like reflections
- that reverse orientation.
-
- A "rigid" transformation is an isometry that preserves orientation
- and can be broken into a proper rotation and a translation.
+ A rigid transformation can be broken into a proper rotation and a translation.
+ while an isometry transformation could also include a reflection.
+ Parameters:
+ *this - must be IsAffine().
+ Translation - [out] Translation vector
+ Rotation - [out] Proper Rotation transformation, ie. R*Transpose(R)=I and det(R)=1
+ Details:
+ If X.DecomposeRigid(T, R) is 1 then X ~ TranslationTransformation(T)*R
+ -1 X ~ ON_Xform(-1) *TranslationTransformation(T)*R
+ where ~ means approximates to within tolerance.
+ DecomposeRigid will find the closest rotation to the linear part of this transformation.
Returns:
- +1: This transformation is an orientation preserving isometry transformation ("rigid and determinant = 1).
- -1: This transformation is an orientation reversing isometry (determinant = -1).
+ +1: This transformation is an rigid transformation.
+ -1: This transformation is an orientation reversing isometry.
0 : This transformation is not an orthogonal transformation.
*/
int IsRigid(double tolerance = ON_ZERO_TOLERANCE) const;
-
-
- /*
- Description:
- A rigid transformation preserves distances and orientation
- and can be broken into a proper rotation and a translation.
- An isometry transformation preserves distance and may include a reflection.
- Parameters:
- *this - must be IsAffine().
- Translation - [out] Translation vector
- Rotation - [out] Proper Rotation transformation, ie. R*Transpose(R)=I and det(R)=1
- Details:
- If X.DecomposeRigid(T, R) is 1 then X ~ TranslationTransformation(T)*R
- -1 X ~ ON_Xform(-1) *TranslationTransformation(T)*R
- where ~ means approximates to within tolerance.
- DecomposeRigid will find the closest rotation to the linear part of this transformation.
- Returns:
- +1: This transformation is an rigid transformation.
- -1: This transformation is an orientation reversing isometry.
- 0 : This transformation is not an orthogonal transformation.
- */
int DecomposeRigid(ON_3dVector& Translation, ON_Xform& Rotation, double tolerance = ON_ZERO_TOLERANCE) const;
/*
diff --git a/opennurbs_xml.cpp b/opennurbs_xml.cpp
index d8ffe254..0860c678 100644
--- a/opennurbs_xml.cpp
+++ b/opennurbs_xml.cpp
@@ -294,8 +294,8 @@ public:
const ON_wString& ConvertDoubleArrayToString(int count) const
{
- constexpr int maxCount = array_val_max;
- if ((count < 1) || (count > maxCount))
+ constexpr int maxCount = 16;
+ if ((count == 0) || (count > maxCount))
return _string_val;
constexpr int maxLen = 30;
@@ -329,8 +329,6 @@ public:
mutable ON_Buffer* _buffer = nullptr;
mutable ON_wString _string_val;
-
- static constexpr int array_val_max = 16;
union
{
bool _bool_val;
@@ -340,7 +338,7 @@ public:
ON_Xform m_xform;
time_t _time_val;
ON_UUID _uuid_val;
- double _array_val[array_val_max] = { 0 };
+ double _array_val[16] = { 0 };
};
ON::LengthUnitSystem _units = ON::LengthUnitSystem::None;
@@ -561,7 +559,7 @@ bool ON_XMLVariant::operator == (const ON_XMLVariant& v) const
return _private->_time_val == v._private->_time_val;
case Types::Matrix:
- for (int i = 0; i < _private->array_val_max; i++)
+ for (int i = 0; i < 16; i++)
{
if (_private->_array_val[i] != v._private->_array_val[i])
return false;
@@ -869,17 +867,6 @@ int ON_XMLVariant::AsInteger(void) const
}
}
-static bool IsValidRealNumber(const ON_wString& s)
-{
- if (s.ContainsNoCase(L"nan"))
- return false;
-
- if (s.ContainsNoCase(L"in")) // ind, inf.
- return false;
-
- return true;
-}
-
double ON_XMLVariant::AsDouble(void) const
{
switch (_private->_type)
@@ -888,10 +875,8 @@ double ON_XMLVariant::AsDouble(void) const
case Types::Float: return _private->_float_val;
case Types::Double: return _private->_double_val;
case Types::Integer: return double (_private->_int_val);
- case Types::String:
- if (IsValidRealNumber(_private->_string_val))
- return ON_wtof(_private->_string_val);
-
+ case Types::String: return ON_wtof(_private->_string_val);
+
default:
return 0.0;
}
@@ -905,10 +890,8 @@ float ON_XMLVariant::AsFloat(void) const
case Types::Float: return _private->_float_val;
case Types::Double: return float(_private->_double_val);
case Types::Integer: return float(_private->_int_val);
- case Types::String:
- if (IsValidRealNumber(_private->_string_val))
- return float(ON_wtof(_private->_string_val));
-
+ case Types::String: return float(ON_wtof(_private->_string_val));
+
default:
return 0.0f;
}
@@ -992,18 +975,18 @@ ON_Xform ON_XMLVariant::AsXform(void) const
switch (_private->_type)
{
case Types::Matrix:
- return _private->m_xform;
+ break;
case Types::String:
if (_private->_string_val.IsValidMatrix())
- {
- StringToPoint(16);
- return _private->m_xform;
- }
+ StringToPoint(16); //////////////////////////////////// Risky
+ break;
default:
return ON_Xform::Zero4x4;
}
+
+ return _private->m_xform;
}
ON_4fColor ON_XMLVariant::AsColor(void) const
@@ -1225,66 +1208,27 @@ ON_XMLVariant::operator ON_Buffer() const
void ON_XMLVariant::StringToPoint(int numValues) const
{
- // 22nd September 2022 John Croudy, https://mcneel.myjetbrains.com/youtrack/issue/RH-77182
- // This function crashed on the Mac inside wcstod_l() which must be getting called from the call to
- // ON_wtof(). The only way that function can fail is if either the input pointers are invalid or the
- // input string or locale is corrupted. I don't have any control over the locale (I don't even know
- // how it's being accessed on the Mac), so all I can do is check the input string. It's unlikely that
- // an incorrectly formatted string (i.e., not a float) would cause a crash, but I can do some simple
- // validation to try and avoid trouble.
+ if ((numValues < 0) || (numValues > 16))
+ return;
- bool good = true;
+ ON_wString s = _private->_string_val + L",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,";
+ auto* p = s.Array();
- if ((numValues < 0) || (numValues > _private->array_val_max))
+ for (int i = 0; i < numValues; i++)
{
- good = false;
- }
- else
- if (_private->_string_val.IsEmpty())
- {
- good = false;
- }
-
- if (good)
- {
- ON_wString s = _private->_string_val + L",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,";
-
- auto* p = static_cast(s);
- for (int i = 0; i < numValues; i++)
+ while (iswspace(*p))
{
- // Skip white space. iswspace() returns 0 for the terminator so we can't go off the end of the buffer.
- while (0 != iswspace(*p))
- {
- p++;
- }
-
- // Quick and simple sanity check at the start of a float value.
- if (isdigit(*p) || (*p == '.') || (*p == '+') || (*p == '-'))
- {
- _private->_array_val[i] = ON_wtof(p);
- }
-
- // Because we've appended a fixed string containing commas, we know the pointer can't go off
- // the end of the buffer while checking for a comma.
- while (*p != L',')
- {
- p++;
- }
-
- // 'p' is now pointing to a comma.
- ON_ASSERT(*p == L',');
-
- // After incrementing it, the worst case scenario is that it's pointing to the terminator.
p++;
}
- }
- else
- {
- // Bad input; clear the result to all zeroes.
- for (int i = 0; i < _private->array_val_max; i++)
+
+ _private->_array_val[i] = ON_wtof(p);
+
+ while (*p != L',')
{
- _private->_array_val[i] = 0.0;
+ p++;
}
+
+ p++;
}
}
@@ -5293,7 +5237,7 @@ void ON_RdkDocumentDefaults::CreateXML(void)
// Misc rendering settings.
ON_XMLParameters p(rendering);
- p.SetParam(ON_RDK_EMBED_SUPPORT_FILES_ON, true); // Only for monitoring. Not loaded.
+ p.SetParam(ON_RDK_EMBED_SUPPORT_FILES_ON, true);
p.SetParam(ON_RDK_DITHERING_ENABLED, false);
p.SetParam(ON_RDK_DITHERING_METHOD, ON_RDK_DITHERING_METHOD_FLOYD_STEINBERG);
p.SetParam(ON_RDK_CUSTOM_REFLECTIVE_ENVIRONMENT, ON_nil_uuid);
diff --git a/opennurbs_xml.h b/opennurbs_xml.h
index 9eb4c6b4..053b93fc 100644
--- a/opennurbs_xml.h
+++ b/opennurbs_xml.h
@@ -236,7 +236,6 @@ typedef bool (*ON_XMLRecurseChildrenCallback)(class ON_XMLNode*, void*);
#define ON_PBR_MATERIAL_CLEARCOAT_BUMP L"pbr-clearcoat-bump"
#define ON_PBR_MATERIAL_CLEARCOAT_ROUGHNESS L"pbr-clearcoat-roughness"
#define ON_PBR_MATERIAL_EMISSION_COLOR L"pbr-emission"
-#define ON_PBR_MATERIAL_EMISSION_MULTIPLIER L"emission-multiplier"
#define ON_PBR_MATERIAL_METALLIC L"pbr-metallic"
#define ON_PBR_MATERIAL_OPACITY L"pbr-opacity"
#define ON_PBR_MATERIAL_OPACITY_IOR L"pbr-opacity-ior"