From 92dfe19314a6c8bf3fd35399af34e1ed9791959d Mon Sep 17 00:00:00 2001 From: fraguada Date: Wed, 15 Nov 2023 23:07:33 +0100 Subject: [PATCH] Revert "Merge pull request #65 from mcneel/update-1700083597-8.x" This reverts commit 79b9408511bc7adf49ca203b5db8440ad2c5f3fd, reversing changes made to 052b5c981c5a877d61bee2f99b3c5f2753a29979. --- opennurbs_3dm_settings.cpp | 3 - opennurbs_archive.cpp | 13 -- opennurbs_brep.h | 2 - opennurbs_color.cpp | 91 ++++++------- opennurbs_color.h | 3 - opennurbs_convex_poly.cpp | 115 +--------------- opennurbs_convex_poly.h | 47 +------ opennurbs_embedded_file.cpp | 39 +----- opennurbs_embedded_file.h | 4 - opennurbs_extensions.cpp | 27 ++-- opennurbs_planesurface.cpp | 103 ++++---------- opennurbs_planesurface.h | 4 +- opennurbs_point.cpp | 18 +-- opennurbs_point.h | 2 - opennurbs_public_version.h | 22 +-- opennurbs_sha1.cpp | 15 +- opennurbs_subd.cpp | 62 +++------ opennurbs_subd.h | 264 ++++++------------------------------ opennurbs_subd_copy.cpp | 4 +- opennurbs_subd_data.cpp | 255 ++++++++-------------------------- opennurbs_subd_data.h | 35 +---- opennurbs_subd_eval.cpp | 1 + opennurbs_subd_fragment.cpp | 113 +++------------ opennurbs_subd_texture.cpp | 10 +- opennurbs_text.cpp | 28 ++-- opennurbs_viewport.cpp | 4 +- opennurbs_xform.h | 44 ++---- opennurbs_xml.cpp | 110 ++++----------- opennurbs_xml.h | 1 - 29 files changed, 326 insertions(+), 1113 deletions(-) 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"