diff --git a/opennurbs_brep.h b/opennurbs_brep.h index 5876194e..3f180e66 100644 --- a/opennurbs_brep.h +++ b/opennurbs_brep.h @@ -1863,6 +1863,9 @@ public: + + + /* Description: Create a brep from a surface. The resulting surface has an outer diff --git a/opennurbs_color.cpp b/opennurbs_color.cpp index a84fae88..5de13a69 100644 --- a/opennurbs_color.cpp +++ b/opennurbs_color.cpp @@ -90,6 +90,15 @@ const ON_Color ON_Color::RandomColor( return color; } +const ON_Color ON_Color::FromHueInRadians( + double hue_in_radians +) +{ + ON_Color c; + c.SetHSV(hue_in_radians, 1.0, 1.0); + return c; +} + ON_Color::ON_Color(unsigned int colorref) : m_color(colorref) { @@ -346,8 +355,7 @@ void ON_Color::SetHSV( const ON_wString ON_Color::ToString( ON_Color::TextFormat format, wchar_t separator, - bool bFormatUnsetColor, - class ON_TextLog& text_log + bool bFormatUnsetColor ) const { ON_wString s; @@ -375,6 +383,9 @@ const ON_wString ON_Color::ToString( case ON_Color::TextFormat::HSVa: format = ON_Color::TextFormat::HSVA; break; + case ON_Color::TextFormat::HashRGBa: + format = ON_Color::TextFormat::HashRGBA; + break; default: break; } @@ -416,11 +427,28 @@ const ON_wString ON_Color::ToString( case ON_Color::TextFormat::HSVA: s = ON_wString::FormatToString(L"%g%lc%g%lc%g%lc%g", Hue(), separator, Saturation(), separator, Value(), separator, FractionAlpha()); break; + case ON_Color::TextFormat::HashRGB: + case ON_Color::TextFormat::HashRGBa: // nonzero alpha handled above + s = ON_wString::FormatToString(L"#%02x%02x%02x", Red(), Green(), Blue()); + break; + case ON_Color::TextFormat::HashRGBA: + s = ON_wString::FormatToString(L"#%02x%02x%02x%02x", Red(), Green(), Blue(), Alpha()); + break; } } return s; } +const ON_wString ON_Color::ToString( + ON_Color::TextFormat format, + wchar_t separator, + bool bFormatUnsetColor, + class ON_TextLog& text_log +) const +{ + return ON_Color::ToString(format, separator, bFormatUnsetColor); +} + void ON_Color::ToText( ON_Color::TextFormat format, wchar_t separator, diff --git a/opennurbs_color.h b/opennurbs_color.h index 9155e8df..16689447 100644 --- a/opennurbs_color.h +++ b/opennurbs_color.h @@ -79,6 +79,8 @@ public: seed - [in] hue_range - [in] range of hues. Use ON_Interval::ZeroToTwoPi for all hues. + 0 = red, pi/3 = yellow, 2pi/3 = green, pi = cyan, + 4pi/3 = blue, 5pi/3 = magenta, 2pi = red saturation_range - [in] range of saturations. Use ON_Interval::ZeroToOne for all saturations. value_range - [in] @@ -105,6 +107,8 @@ public: seed - [in] hue_range - [in] range of hues. Use ON_Interval::ZeroToTwoPi for all hues. + 0 = red, pi/3 = yellow, 2pi/3 = green, pi = cyan, + 4pi/3 = blue, 5pi/3 = magenta, 2pi = red saturation_range - [in] range of saturations. Use ON_Interval::ZeroToOne for all saturations. value_range - [in] @@ -119,6 +123,20 @@ public: ON_Interval value_range ); + /// + /// Get the saturated color with the specified hue. + /// + /// + /// 0 = red, pi/3 = yellow, 2pi/3 = green, pi = cyan, + /// 4pi/3 = blue, 5pi/3 = magenta, 2pi = red + /// + /// + /// A saturated color with the specified hue. + /// + static const ON_Color FromHueInRadians( + double hue_in_radians + ); + // If you need to use shifting to convert RGBA components to and from // an unsigned int ON_COlor value and you want your code to work // on both little and big endian computers, use the RGBA_shift enum. @@ -229,11 +247,9 @@ public: double alpha // alpha in range 0.0 to 1.0 (0.0 = opaque, 1.0 = transparent) ); - // Hue() returns an angle in the range 0 to 2*pi - // - // 0 = red, pi/3 = yellow, 2*pi/3 = green, - // pi = cyan, 4*pi/3 = blue,5*pi/3 = magenta, - // 2*pi = red + // Hue() returns an angle in radians in the range 0 to 2*pi. + // 0 = red, pi/3 = yellow, 2pi/3 = green, pi = cyan, + // 4pi/3 = blue, 5pi/3 = magenta, 2pi = red double Hue() const; // Returns 0.0 (gray) to 1.0 (saturated) @@ -242,10 +258,20 @@ public: // Returns 0.0 (black) to 1.0 (white) double Value() const; + /// + /// Specify a color using HSV (hue, saturation, value). + /// + /// + /// hue in radians + /// 0 = red, pi/3 = yellow, 2pi/3 = green, pi = cyan, + /// 4pi/3 = blue, 5pi/3 = magenta, 2pi = red + /// + /// satuation 0.0 = gray, 1.0 = saturated + /// value 0=black, 1.0 = bright void SetHSV( - double h, // hue in radians 0 to 2*pi - double s, // satuation 0.0 = gray, 1.0 = saturated - double v // value + double h, + double s, + double v ); /// @@ -317,24 +343,49 @@ public: /// hue (0 to 2pi), saturation (0 to 1), value (0 to 1), alpha (0 to 1) as floating point values. /// HSVA = 12, + + /// + /// red,green,blue as two hex digit hexadecimal numbers preceded with a hash. (#RRGGBB) + /// + HashRGB = 13, + + /// + /// red,green,blue as two hex digit hexadecimal numbers preceded with a hash. alpha is appended if it is not zero. (#RRGGBBaa) + /// + HashRGBa = 14, + + /// + /// red,green,blue,alpha as two hex digit hexadecimal numbers preceded with a hash. (#RRGGBBAA). + /// + HashRGBA = 15, }; /* Parameters: format - [in] separator - [in] + Separarates the values. + 0 to use UNICODE comma. + (Ignored when the format is HashRGB*.) character to separate numbers (unicode code point - UTF-16 surrogate pairs not supported) pass 0 for default. bFormatUnsetColor - [in] If true, ON_Color::UnsetColor will return "UnsetColor". Otherwise ON_Color::UnsetColor will return the empty string. - text_log - [in] - destination of the text. */ + const ON_wString ToString( + ON_Color::TextFormat format, + wchar_t separator, + bool bFormatUnsetColor + ) const; + + + + /*MISTAKE - BUT IT SNUCK INTO THE SDK - IGNORE*/ const ON_wString ToString( ON_Color::TextFormat format, wchar_t separator, bool bFormatUnsetColor, - class ON_TextLog& text_log + class ON_TextLog& ignored_parameter ) const; /* @@ -342,6 +393,8 @@ public: format - [in] If format is ON_Color::TextFormat::Unset, then text_log.ColorFormat is used. separator - [in] + 0 to use UNICODE comma. + (Ignored when the format is HashRGB*.) character to separate numbers (unicode code point - UTF-16 surrogate pairs not supported) pass 0 for default. bFormatUnsetColor - [in] diff --git a/opennurbs_geometry.cpp b/opennurbs_geometry.cpp index 67d560fb..b257d77d 100644 --- a/opennurbs_geometry.cpp +++ b/opennurbs_geometry.cpp @@ -106,6 +106,15 @@ ON_Geometry::GetBoundingBox( // returns true if successful return rc; } +const ON_BoundingBox ON_Geometry::TightBoundingBox() const +{ + ON_BoundingBox bbox = ON_BoundingBox::NanBoundingBox; + // call virtual function + if (this->GetTightBoundingBox(bbox, false, nullptr) && bbox.IsValid()) + return bbox; + return ON_BoundingBox::NanBoundingBox; +} + bool ON_Geometry::GetTightBoundingBox( ON_BoundingBox& tight_bbox, bool bGrowBoxAsInt, diff --git a/opennurbs_geometry.h b/opennurbs_geometry.h index 0bbb0775..e74bf4a6 100644 --- a/opennurbs_geometry.h +++ b/opennurbs_geometry.h @@ -222,6 +222,8 @@ public: const class ON_Xform* xform = nullptr ) const; + const ON_BoundingBox TightBoundingBox() const; + // Description: // Some objects cache bounding box information. // If you modify an object, then call ClearBoundingBox() diff --git a/opennurbs_material.cpp b/opennurbs_material.cpp index 2d6ab5ff..8003f6fe 100644 --- a/opennurbs_material.cpp +++ b/opennurbs_material.cpp @@ -2420,7 +2420,7 @@ void ON_Texture::SetRotation(double rotation) m_uvw.DecomposeTextureMapping(offset, repeat, r); - m_uvw = ON_Xform::TextureMapping(offset, repeat, ON_3dPoint(0.0, 0.0, rotation)); + m_uvw = ON_Xform::TextureMapping(offset, repeat, ON_3dPoint(0.0, 0.0, rotation * ON_DEGREES_TO_RADIANS)); } double ON_Texture::Rotation() const @@ -2429,7 +2429,7 @@ double ON_Texture::Rotation() const m_uvw.DecomposeTextureMapping(offset, repeat, rotation); - return rotation.z; + return rotation.z * ON_RADIANS_TO_DEGREES; } diff --git a/opennurbs_mesh.cpp b/opennurbs_mesh.cpp index 435c8566..78b5af50 100644 --- a/opennurbs_mesh.cpp +++ b/opennurbs_mesh.cpp @@ -1309,6 +1309,22 @@ static void Internal_PrintMeshArrayHash(ON_TextLog& text_log, const ON_SimpleArr Internal_PrintMeshArrayHash(text_log, hash, prefix, bNewLine); } +static void Internal_PrintMeshArrayHash(ON_TextLog& text_log, const ON_SimpleArray& a, const wchar_t* prefix, bool bNewLine) +{ + ON_SHA1 sha1; + sha1.AccumulateDoubleArray(a.Count() * 2, (const double*)a.Array()); + const ON_SHA1_Hash hash = sha1.Hash(); + Internal_PrintMeshArrayHash(text_log, hash, prefix, bNewLine); +} + +static void Internal_PrintMeshArrayHash(ON_TextLog& text_log, const ON_SimpleArray& a, const wchar_t* prefix, bool bNewLine) +{ + ON_SHA1 sha1; + sha1.AccumulateInteger32Array(a.Count(), (const ON__INT32*)a.Array()); + const ON_SHA1_Hash hash = sha1.Hash(); + Internal_PrintMeshArrayHash(text_log, hash, prefix, bNewLine); +} + static void Internal_PrintMeshArrayHash(ON_TextLog& text_log, const ON_SimpleArray& a, const wchar_t* prefix, bool bNewLine) { ON_SHA1 sha1; @@ -1493,16 +1509,13 @@ void ON_Mesh::Dump( ON_TextLog& dump ) const } else { - ON_2fPoint tp = m_T[i]; - p.x = tp.x; - p.y = tp.y; - dump.Print("m_T[%d] = (%g,%g)\n",i,p.x,p.y); + const ON_2dPoint tp(m_T[i]); + dump.Print("m_T[%d] = (%g,%g)\n",i,tp.x,tp.y); } } } } - if ( HasSurfaceParameters() ) { dump.Print("%d mesh vertex surface parameters:\n",m_S.Count()); @@ -1518,13 +1531,59 @@ void ON_Mesh::Dump( ON_TextLog& dump ) const } else { - ON_2dPoint srfuv = m_S[i]; - dump.Print("m_S[%d] = (%g,%g)\n",i,srfuv.x,srfuv.y); + const ON_2dPoint srfuv = m_S[i]; + dump.Print("m_S[%d] = (%g,%g)\n",i, srfuv.x, srfuv.y); } } } } + if (this->HasVertexColors()) + { + dump.Print("%d mesh vertex colors:\n", m_C.Count()); + { + const ON_TextLogIndent indent2(dump); + Internal_PrintMeshArrayHash(dump, m_C, L"m_C array hash", true); + for (i = 0; i < vcount; i++) + { + if (i == half_max && 2 * half_max < vcount) + { + dump.Print("...\n"); + i = vcount - half_max; + } + else + { + const ON_wString s = m_C[i].ToString(ON_Color::TextFormat::HashRGBa, 0, true); + dump.Print(L"m_C[%d] = %s\n", i, static_cast(s)); + } + } + } + } + + + if (this->HasPrincipalCurvatures()) + { + dump.Print("%d mesh vertex principal curvatures:\n", m_K.Count()); + { + const ON_TextLogIndent indent2(dump); + Internal_PrintMeshArrayHash(dump, m_K, L"m_K array hash", true); + for (i = 0; i < vcount; i++) + { + if (i == half_max && 2 * half_max < vcount) + { + dump.Print("...\n"); + i = vcount - half_max; + } + else + { + const ON_SurfaceCurvature k = m_K[i]; + dump.Print("m_K[%d] = (%g,%g)\n", i, k.k1, k.k2); + } + } + } + } + + dump.Print("%d mesh faces:\n",m_F.Count()); { const ON_TextLogIndent indent2(dump); @@ -4286,9 +4345,79 @@ bool ON_Mesh::HasPrincipalCurvatures() const bool ON_Mesh::HasVertexColors() const { const int vertex_count = VertexCount(); - return ( vertex_count > 0 && m_C.Count() == vertex_count ) ? true : false; + return (vertex_count > 0 && m_C.Count() == vertex_count) ? true : false; } +bool ON_Mesh::HasVertexColors( + ON_MappingTag color_tag +) const +{ + return this->HasVertexColors() && color_tag == this->m_Ctag; +} + +void ON_Mesh::ClearVertexColors() +{ + this->m_C.SetCount(0); + this->m_Ctag = ON_MappingTag::Unset; +} + +bool ON_Mesh::SetDraftAngleColorAnalysisColors( + bool bLazy, + ON_3dVector up, + ON_Interval angle_range_in_radians, + ON_Interval hue_range_in_radians +) +{ + const ON_MappingTag Ctag = ON_MappingTag::DraftAngleColorAnalysisTag(up, angle_range_in_radians, hue_range_in_radians); + if (bLazy && HasVertexColors() && this->m_Ctag == Ctag) + return true; + + this->ClearVertexColors(); + + if (false == this->HasVertexNormals()) + return false; + + const unsigned count = this->m_N.Count(); + this->m_C.Reserve(count); + for (unsigned i = 0; i < count; ++i) + { + const ON_Color c = ON_MappingTag::DraftAngleColor(up, angle_range_in_radians, hue_range_in_radians, ON_3dVector(this->m_N[i])); + this->m_C.Append(c); + } + this->m_Ctag = Ctag; + + return true; +} + +bool ON_Mesh::SetCurvatureColorAnalysisColors( + bool bLazy, + const ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians +) +{ + const ON_MappingTag Ctag = ON_MappingTag::CurvatureColorAnalysisTag(kappa_style, kappa_range, hue_range_in_radians); + if (bLazy && HasVertexColors() && this->m_Ctag == Ctag) + return true; + + this->ClearVertexColors(); + + if (false == this->HasPrincipalCurvatures()) + return false; + + const unsigned count = this->m_K.Count(); + this->m_C.Reserve(count); + for (unsigned i = 0; i < count; ++i) + { + const ON_Color c = ON_MappingTag::CurvatureColor(kappa_style, kappa_range, hue_range_in_radians, this->m_K[i]); + this->m_C.Append(c); + } + this->m_Ctag = Ctag; + + return true; +} + + void ON_Mesh::InvalidateBoundingBoxes() { InvalidateVertexBoundingBox(); @@ -9220,6 +9349,84 @@ const ON_SurfaceCurvature ON_SurfaceCurvature::CreateFromPrincipalCurvatures( return k; } +double ON_SurfaceCurvature::KappaValue(ON::curvature_style kappa_style) const +{ + double k; + switch (kappa_style) + { + case ON::gaussian_curvature: + k = this->GaussianCurvature(); + break; + + case ON::mean_curvature: + // fabs() is correct here. + // Turns out the vast majority of users don't appear to care about + // signed mean curvature and find it confusing. + k = fabs(this->MeanCurvature()); + break; + + case ON::min_curvature: + k = this->MinimumRadius(); + break; + + case ON::max_curvature: + k = this->MaximumRadius(); + break; + + default: + k = ON_DBL_QNAN; + break; + } + return k; +} + +const ON_Color ON_MappingTag::CurvatureColor( + ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians, + ON_SurfaceCurvature K +) +{ + // This is the curvature analysis color used by the current version of Rhino. + // The code can be updated as the method for assigning a color to surface curvatures changes. + + const double k = K.KappaValue(kappa_style); + + if (ON_IS_NAN(k)) + return ON_Color::UnsetColor; + + // convert k to hue + const double mn = kappa_range.m_t[0]; + const double mx = kappa_range.m_t[1]; + double f; + if (mn != mx) + { + const double d = 1.0 / (mx - mn); + f = (mx - k) * d; + if (f <= 0.0) + f = 0.0; + else if (f >= 1.0) + f = 1.0; + } + else if (mn == mx) + { + if (k > mn) + f = 0.0; + else if (k < mn) + f = 1.0; + else + f = 0.5; + } + else + return ON_Color::UnsetColor; + + + if (f >= 0.0 && f <= 1.0) + return ON_Color::FromHueInRadians(hue_range_in_radians.ParameterAt(f)); + + return ON_Color::UnsetColor; +} + bool ON_SurfaceCurvature::IsSet() const { return (ON_UNSET_VALUE < k1&& k1 < ON_UNSET_POSITIVE_VALUE&& ON_UNSET_VALUE < k2&& k2 < ON_UNSET_POSITIVE_VALUE); @@ -9238,36 +9445,67 @@ bool ON_SurfaceCurvature::IsUnset() const double ON_SurfaceCurvature::GaussianCurvature() const { - return k1*k2; + if (ON_IS_VALID(k1) && ON_IS_VALID(k2)) + { + return k1 * k2; + } + + return ON_DBL_QNAN; } double ON_SurfaceCurvature::MeanCurvature() const { - return 0.5*(k1+k2); + if (ON_IS_VALID(k1) && ON_IS_VALID(k2)) + { + return 0.5 * (k1 + k2); + } + + return ON_DBL_QNAN; } double ON_SurfaceCurvature::MinimumRadius() const { - double k; - k = (fabs(k1)>=fabs(k2)) ? fabs(k1) : fabs(k2); // k = maximum directional curvature - k = ( k > 1.0e-300 ) ? 1.0/k : 1.0e300; // 1/k = minimum radius of curvature - return k; + if (ON_IS_VALID(k1) && ON_IS_VALID(k2)) + { + // k = maximum directional curvature + const double k = (fabs(k1) >= fabs(k2)) ? fabs(k1) : fabs(k2); + + // 1/k = minimum radius of curvature + return + (k > (1.0 / ON_SurfaceCurvature::InfinteRadius)) + ? 1.0 / k + : ON_SurfaceCurvature::InfinteRadius; + } + + return ON_DBL_QNAN; } double ON_SurfaceCurvature::MaximumRadius() const { - double k; - if ( k1*k2 <= 0.0 ) { - // if principal curvatures have opposite signs, there - // is a direction with zero directional curvature - k = 0.0; + if (ON_IS_VALID(k1) && ON_IS_VALID(k2)) + { + // k = minimum directional curvature + double k; + if (k1 * k2 <= 0.0 || fabs(k1) <= 1e-300 || fabs(k2) <= 1e-300) + { + // If principal curvatures have opposite signs, + // there is a direction with zero directional curvature. + k = 0.0; + } + else + { + // The minimum directional curvaature is in a principal curvature direction. + k = (fabs(k1) <= fabs(k2)) ? fabs(k1) : fabs(k2); + } + + // 1/k = maximum radius of curvature + return + (k > (1.0 / ON_SurfaceCurvature::InfinteRadius)) + ? 1.0 / k + : ON_SurfaceCurvature::InfinteRadius; } - else { - k = (fabs(k1)<=fabs(k2)) ? fabs(k1) : fabs(k2); - } - // k = minimum directional curvature - k = ( k > 1.0e-300 ) ? 1.0/k : 1.0e300; // 1/k = maximum radius of curvature - return k; + + return ON_DBL_QNAN; } ON_MeshTopology::ON_MeshTopology() @@ -12044,6 +12282,166 @@ const ON_Xform ON_MappingTag::Transform() const return TransformIsIdentity() ? ON_Xform::IdentityTransformation : m_mesh_xform; } +const ON_SHA1_Hash ON_MappingTag::CurvatureColorAnalysisParametersHash( + ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians +) +{ + ON_SHA1 sha1; + + // The uuid is accumulated because an int,double,double could easily + // be the intput data int many unrelated contexts. This sha1 is used + // to avoid expensive recalculations of curvatures and their false colors. + const ON_UUID uniqueness_boost = ON_MappingTag::CurvatureColorAnalysisId; + sha1.AccumulateId(uniqueness_boost); + + const unsigned u = (unsigned)kappa_style; + sha1.AccumulateInteger32(u); + + sha1.AccumulateDoubleArray(2, kappa_range.m_t); + + sha1.AccumulateDoubleArray(2, hue_range_in_radians.m_t); + + return sha1.Hash(); +} + +ON__UINT32 ON_MappingTag::CurvatureColorAnalysisParametersCRC32( + ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians +) +{ + return ON_MappingTag::CurvatureColorAnalysisParametersHash(kappa_style,kappa_range, hue_range_in_radians).CRC32(0); +} + +const ON_MappingTag ON_MappingTag::CurvatureColorAnalysisTag( + ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians +) +{ + ON_MappingTag mt = ON_MappingTag::Unset; + + mt.m_mapping_id = ON_MappingTag::CurvatureColorAnalysisId; + mt.m_mapping_type = ON_TextureMapping::TYPE::false_colors; + + // DO NOT INCLUDE anything in the crc that does not directly control vertex colors. + // This value is used to determine when the parameters used to calculate the vertex + // colors have changed. + mt.m_mapping_crc = ON_MappingTag::CurvatureColorAnalysisParametersCRC32(kappa_style, kappa_range, hue_range_in_radians); + + // The m_mesh_xform in meaningless for false color curvature analysis, + // but setting it to the identity greases the wheels when downstream + // code looks at it for unknown reasons. + mt.m_mesh_xform = ON_Xform::IdentityTransformation; + + return mt; +} + +const ON_SHA1_Hash ON_MappingTag::DraftAngleColorAnalysisParametersHash( + ON_3dVector up, + ON_Interval angle_range_in_radians, + ON_Interval hue_range_in_radians +) +{ + ON_SHA1 sha1; + + // The uuid is accumulated because an int,double,double could easily + // be the intput data int many unrelated contexts. This sha1 is used + // to avoid expensive recalculations of curvatures and their false colors. + const ON_UUID uniqueness_boost = ON_MappingTag::DraftAngleColorAnalysisId; + sha1.AccumulateId(uniqueness_boost); + sha1.AccumulateDoubleArray(3, &up.x); + sha1.AccumulateDoubleArray(2, angle_range_in_radians.m_t); + sha1.AccumulateDoubleArray(2, hue_range_in_radians.m_t); + return sha1.Hash(); +} + +ON__UINT32 ON_MappingTag::DraftAngleColorAnalysisParametersCRC32( + ON_3dVector up, + ON_Interval angle_range_in_radians, + ON_Interval hue_range_in_radians +) +{ + return ON_MappingTag::DraftAngleColorAnalysisParametersHash(up, angle_range_in_radians, hue_range_in_radians).CRC32(0); +} + + +const ON_MappingTag ON_MappingTag::DraftAngleColorAnalysisTag( + ON_3dVector up, + ON_Interval angle_range_in_radians, + ON_Interval hue_range_in_radians +) +{ + ON_MappingTag mt = ON_MappingTag::Unset; + + mt.m_mapping_id = ON_MappingTag::DraftAngleColorAnalysisId; + mt.m_mapping_type = ON_TextureMapping::TYPE::false_colors; + + // DO NOT INCLUDE anything in the crc that does not directly control vertex colors. + // This value is used to determine when the parameters used to calculate the vertex + // colors have changed. + mt.m_mapping_crc = ON_MappingTag::DraftAngleColorAnalysisParametersCRC32(up, angle_range_in_radians, hue_range_in_radians); + + // The m_mesh_xform in meaningless for false color curvature analysis, + // but setting it to the identity greases the wheels when downstream + // code looks at it for unknown reasons. + mt.m_mesh_xform = ON_Xform::IdentityTransformation; + + return mt; +} + +const ON_Color ON_MappingTag::DraftAngleColor( + ON_3dVector up, + ON_Interval draft_angle_range_in_radians, + ON_Interval hue_range_in_radians, + ON_3dVector surface_normal +) +{ + for (;;) + { + if (false == ON_IsValid(draft_angle_range_in_radians.m_t[0])) + break; + if (false == ON_IsValid(draft_angle_range_in_radians.m_t[1])) + break; + + const double a0 = ON_HALFPI - draft_angle_range_in_radians[0]; + const double a1 = ON_HALFPI - draft_angle_range_in_radians[1]; + const double mn = cos(a0); + const double mx = cos(a1); + + const double n_dot_up = surface_normal * up; + double h; + + if (fabs(mn - mx) <= 1e-8) + { + if (n_dot_up < mn && n_dot_up < mx) + h = hue_range_in_radians[0]; + else if (n_dot_up > mn && n_dot_up > mx) + h = hue_range_in_radians[1]; + else + h = hue_range_in_radians.ParameterAt(0.5); + } + else if (mn != mx) + { + double t = (n_dot_up - mn) / (mx - mn); + if (t <= 0.0) + h = hue_range_in_radians[0]; + else if (t >= 1.0) + h = hue_range_in_radians[1]; + else + h = hue_range_in_radians.ParameterAt(t); + } + else + break; + + return ON_Color::FromHueInRadians(h); + } + return ON_Color::UnsetColor; +} + + bool ON_MappingTag::TransformIsIdentity() const { return ON_MappingTag::TransformTreatedIsIdentity(&m_mesh_xform); @@ -12072,22 +12470,28 @@ ON_MappingTag::ON_MappingTag(const ON_TextureMapping & mapping, const ON_Xform * void ON_MappingTag::Dump( ON_TextLog& text_log ) const { - text_log.Print("Texture/color mapping tag:\n"); if (text_log.IsTextHash()) { // The code is a mess with respect to mapping tags and they are // often mutable or changed with const/cast in unpredictable ways. + text_log.Print("Texture/color mapping tag:\n"); text_log.Print(" ...\n"); return; } - const ON_TextLogIndent indent1(text_log); + const ON_TextLog::LevelOfDetail lod = text_log.GetLevelOfDetail(); - if (0 == ON_MappingTag::CompareAll(ON_MappingTag::Unset, *this)) + if (lod >= ON_TextLog::LevelOfDetail::Maximum) + { + text_log.Print("Texture/color mapping tag:\n"); + text_log.PushIndent(); + } + + if (ON_MappingTag::Unset == *this) { text_log.Print("ON_MappingTag::Unset\n"); } - else if (0 == ON_MappingTag::CompareAll(ON_MappingTag::SurfaceParameterMapping, *this)) + else if (ON_MappingTag::SurfaceParameterMapping == *this) { text_log.Print("ON_MappingTag::SurfaceParameterMapping\n"); } @@ -12136,12 +12540,34 @@ void ON_MappingTag::Dump( ON_TextLog& text_log ) const text_log.Print(m_mapping_id); if (m_mapping_id == ON_MappingTag::SurfaceParameterMapping.m_mapping_id) text_log.Print(" = ON_MappingTag::SurfaceParameterMapping.m_mapping_id"); + else if (m_mapping_id == ON_MappingTag::CurvatureColorAnalysisId) + text_log.Print(" = ON_MappingTag::CurvatureColorAnalysisId"); + else if (m_mapping_id == ON_MappingTag::DraftAngleColorAnalysisId) + text_log.Print(" = ON_MappingTag::DraftAngleColorAnalysisId"); text_log.PrintNewLine(); text_log.Print("mapping crc: %08x\n", m_mapping_crc); - text_log.Print("mesh xform:\n"); - const ON_TextLogIndent indent2(text_log); - text_log.Print(m_mesh_xform); + + text_log.Print("mesh xform:"); + if (ON_Xform::IdentityTransformation == m_mesh_xform) + text_log.Print(" ON_Xform::IdentityTransformation\n"); + else if (ON_Xform::ZeroTransformation == m_mesh_xform) + text_log.Print(" ON_Xform::ZeroTransformation\n"); + else if (ON_Xform::Zero4x4 == m_mesh_xform) + text_log.Print(" ON_Xform::Zero4x4\n"); + else if (ON_Xform::Unset == m_mesh_xform) + text_log.Print(" ON_Xform::Unset\n"); + else + { + text_log.PrintNewLine(); + const ON_TextLogIndent indent2(text_log); + text_log.Print(m_mesh_xform); + } + } + + if (lod >= ON_TextLog::LevelOfDetail::Maximum) + { + text_log.PopIndent(); } } @@ -12268,6 +12694,48 @@ int ON_MappingTag::CompareAll(const ON_MappingTag& lhs, const ON_MappingTag& rhs return lhs.m_mesh_xform.Compare(rhs.m_mesh_xform); } +bool operator==(const ON_MappingTag& lhs, const ON_MappingTag& rhs) +{ + if (lhs.m_mapping_type == rhs.m_mapping_type && lhs.m_mapping_id == rhs.m_mapping_id) + { + if (ON_TextureMapping::TYPE::no_mapping == lhs.m_mapping_type && ON_nil_uuid == lhs.m_mapping_id) + { + // m_mapping_crc and m_mesh_xform are meaningless and are ignored + return true; + } + + if (ON_TextureMapping::TYPE::srfp_mapping == lhs.m_mapping_type && ON_MappingTag::SurfaceParameterMapping.m_mapping_id == lhs.m_mapping_id) + { + // m_mesh_xform is meaningless and is ignored + // (m_mapping_crc can be from a uvw texture coordinate transformation and must be checked) + return lhs.m_mapping_crc == rhs.m_mapping_crc; + } + } + + return lhs.m_mapping_crc == rhs.m_mapping_crc && 0 == lhs.m_mesh_xform.Compare(rhs.m_mesh_xform); +} + +bool operator!=(const ON_MappingTag& lhs, const ON_MappingTag& rhs) +{ + if (lhs.m_mapping_type != rhs.m_mapping_type || false == (lhs.m_mapping_id == rhs.m_mapping_id)) + return true; + + if (ON_TextureMapping::TYPE::no_mapping == lhs.m_mapping_type && ON_nil_uuid == lhs.m_mapping_id) + { + // m_mapping_crc and m_mesh_xform are meaningless and are ignored + return false; + } + + if (ON_TextureMapping::TYPE::srfp_mapping == lhs.m_mapping_type && ON_MappingTag::SurfaceParameterMapping.m_mapping_id == lhs.m_mapping_id) + { + // m_mesh_xform is meaningless and is ignored + // (m_mapping_crc can be from a uvw texture coordinate transformation and must be checked) + return lhs.m_mapping_crc != rhs.m_mapping_crc; + } + + return (lhs.m_mapping_crc != rhs.m_mapping_crc || 0 != lhs.m_mesh_xform.Compare(rhs.m_mesh_xform)); +} + int ON_MappingTag::CompareAllFromPointer(const ON_MappingTag* lhs, const ON_MappingTag* rhs) { if (lhs == rhs) diff --git a/opennurbs_mesh.h b/opennurbs_mesh.h index 1c3668e4..f0e697d2 100644 --- a/opennurbs_mesh.h +++ b/opennurbs_mesh.h @@ -3054,8 +3054,6 @@ public: ON_SimpleArray m_part; }; - - class ON_CLASS ON_MappingTag { public: @@ -3063,8 +3061,204 @@ public: ON_MappingTag(const ON_TextureMapping& mapping,const ON_Xform* xform); static const ON_MappingTag Unset; + + /// + /// id = ON_TextureMapping::SurfaceParameterTextureMappingId + /// type = ON_TextureMapping::TYPE::srfp_mapping + /// static const ON_MappingTag SurfaceParameterMapping; + // {639E9144-1C1A-4bba-8248-D330F50D7B69} + static const ON_UUID CurvatureColorAnalysisId; + + /// + /// + /// + /// + /// When in doubt, use ON_MappingTag::CurvatureColorHueRangeDefault. + /// + /// + /// The SHA1 hash used to indentify the parameters used to + /// convert the surface principal curvatures to a color. + /// + static const ON_SHA1_Hash CurvatureColorAnalysisParametersHash( + ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians + ); + + /// + /// + /// + /// + /// When in doubt, use ON_MappingTag::CurvatureColorHueRangeDefault. + /// + /// + /// The 32 bit CRC used to indentify the parameters used to + /// convert the surface principal curvatures to a color. + /// + static ON__UINT32 CurvatureColorAnalysisParametersCRC32( + ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians + ); + + /// + /// Get the mapping tag used to identify meshes whose vertex colors + /// are set by converting surface principal curvatures to a color. + /// + /// + /// + /// + /// When in doubt, use ON_MappingTag::CurvatureColorHueRangeDefault. + /// + /// + /// A mapping tag that has id = ON_MappingTag::CurvatureAnalysisId + /// and a CRC that depends on kappa_style and kappa_range. + /// + static const ON_MappingTag CurvatureColorAnalysisTag( + ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians + ); + + /// + /// The default curvature color analysis hue range used + /// by the Rhino CurvatureAnalysis command. + /// + /// 0 to 4pi/3 (red to blue) + static const ON_Interval CurvatureColorHueRangeDefault; + + /// + /// Used to convert a curvature value to a color. + /// + /// + /// Specifies what curvature value to used. + /// + /// + /// A range that is used to convert kappa values to colors. + /// This interval may be increasing, decreasing, or a singleton. + /// A kappa value equal to kappa_range[0] is mapped to hue_range[0]. + /// A kappa value equal to kappa_range[1] is mapped to hue_range[1]. + /// A kappa value k in between kappa_range[0] and kappa_range[1] + /// is mapped to the saturated color with + /// hue = hue_range.ParameterAt(kappa_range.NormalizedParameterAt(k)). + /// Kappa values outside the kappa_range inteval are mapped to the hue + /// assigned to the nearest end of the kappa_range interval. + /// + /// + /// When in doubt, pass ON_MappingTag::CurvatureHueRangeDefault. + /// The range of color hues in radians corresponding to kappa_range. + /// This interval may be increasing or decreasing. + /// A kappa value k in between kappa_range[0] and kappa_range[1] + /// is mapped to the saturated color with + /// hue = hue_range.ParameterAt(kappa_range.NormalizedParameterAt(k)). + /// If k is outside the range specified by kappa_range, + /// the appropriate + /// + /// + /// The color used by the current Rhino CurvatureAnalysis command. + /// + static const ON_Color CurvatureColor( + ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians, + ON_SurfaceCurvature K + ); + + // {F08463F4-22E2-4cf1-B810-F01925446D71} + static const ON_UUID DraftAngleColorAnalysisId; + + /// + /// + /// + /// + /// When in doubt, use ON_MappingTag::DraftAngleColorHueRangeDefault. + /// + /// + /// The SHA1 hash used to indentify the parameters used to + /// convert the surface normal to a draft angle analysis color. + /// + static const ON_SHA1_Hash DraftAngleColorAnalysisParametersHash( + ON_3dVector up, + ON_Interval angle_range_in_radians, + ON_Interval hue_range_in_radians + ); + + /// + /// + /// + /// + /// When in doubt, use ON_MappingTag::DraftAngleColorHueRangeDefault. + /// + /// + /// The 32 bit CRC used to indentify the parameters used to + /// convert the surface normal to a draft angle analysis color. + /// + static ON__UINT32 DraftAngleColorAnalysisParametersCRC32( + ON_3dVector up, + ON_Interval angle_range_in_radians, + ON_Interval hue_range_in_radians + ); + + /// + /// Get the mapping tag used to identify meshes whose vertex colors + /// are set by converting surface normal to a draft angle color. + /// + /// + /// + /// + /// When in doubt, use ON_MappingTag::DraftAngleColorHueRangeDefault. + /// + /// + /// A mapping tag that has id = ON_MappingTag::DraftAngleMappingTag + /// and a CRC that depends on up and angle_range_in_radians. + /// + static const ON_MappingTag DraftAngleColorAnalysisTag( + ON_3dVector up, + ON_Interval angle_range_in_radians, + ON_Interval hue_range_in_radians + ); + + /// + /// The default draft angle color analysis hue range used + /// by the Rhino CraftAngleAnalysis command. + /// + /// + /// 0 to 4pi/3 (red to blue) + /// + static const ON_Interval DraftAngleColorHueRangeDefault; + + /// + /// Used to get the color the current Rhino DraftAngleAnalysis command + /// assigns to a specified surface normal. + /// + /// + /// A unit vector (length = 1) that specifies the up direction. + /// + /// + /// An draft angle of 0 corresponds to the up vector and a surface normal being orthogonal. + /// Draft angles > 0 correspond to to a surface normal and up having a positive dot product. + /// Draft angles < 0 correspond to to a surface normal and up having a negative dot product. + /// A draft angle of pi/2 (90 degrees) occurs when the surface normal and up are parallel. + /// A draft angle of -pi/2 (-90 degrees) occurs when the surface normal and up are antiparallel. + /// + /// + /// hue range in radians. + /// 0 = red, pi/3 = yellow, 2pi/3 = green, pi = cyan, + /// 4pi/3 = blue, 5pi/3 = magenta, 2pi = red + /// A draft angle = draft_angle_range_in_radians[0] is assigned a color hue = hue_range_in_radians[0] + /// and a draft angle = draft_angle_range_in_radians[1] is assigned a color hue = hue_range_in_radians[1]. + /// + /// + /// + static const ON_Color DraftAngleColor( + ON_3dVector up, + ON_Interval draft_angle_range_in_radians, + ON_Interval hue_range_in_radians, + ON_3dVector surface_normal + ); + void Default(); bool Write(ON_BinaryArchive&) const; bool Read(ON_BinaryArchive&); @@ -3102,17 +3296,35 @@ public: */ bool IsDefaultSurfaceParameterMapping() const; - // Identifies the mapping used to create the texture - // coordinates and records transformations applied + // m_mapping_id identifies the mapping used to create + // the texture coordinates and/or false colors. + ON_UUID m_mapping_id = ON_nil_uuid; + + ON_TextureMapping::TYPE m_mapping_type = ON_TextureMapping::TYPE::no_mapping; + + // The m_mapping_crc is a CRC of a SHA1 hash of the parameters used in + // the calculation to set the current texture coordinates and/or vertex colors. + // This CRC is used to detect when the the texture coordinates and/or false colors need to be updated. + // (Saving the SHA1 hash itself would be better, but changing m_mapping_crc to a SHA1 hash would break the SDK.) + // + // When m_mapping_id = ON_nil_uuid and m_mapping_type = ON_TextureMapping::TYPE::no_mapping, + // m_mapping_crc has no meaning and is ignored by operator== and operator!=. + // + // When m_mapping_id = ON_MappingTag::SurfaceParameterMapping.m_mapping_id and m_mapping_type = ON_TextureMapping::TYPE::srfp_mapping, + // m_mapping_crc can be set from a uvw texture coordinate transformation. + ON__UINT32 m_mapping_crc = 0; + + // It and records transformations applied // to the mesh after the texture coordinates were // calculated. If the texture mapping does not // change when the mesh is transformed, then set // m_mesh_xform to zero so that compares will work right. - // // - ON_UUID m_mapping_id = ON_nil_uuid; // ON_TextureMapping::m_mapping_id - ON_TextureMapping::TYPE m_mapping_type = ON_TextureMapping::TYPE::no_mapping; // ON_TextureMapping::m_type - ON__UINT32 m_mapping_crc = 0; // ON_TextureMapping::MappingCRC() (from decades ago - a sha1 would be better when SDK can break) + // When m_mapping_id = ON_nil_uuid and m_mapping_type = ON_TextureMapping::TYPE::no_mapping, + // m_mesh_xform has no meaning and is ignored by operator== and operator!=. + // + // When m_mapping_id = ON_MappingTag::SurfaceParameterMapping.m_mapping_id and m_mapping_type = ON_TextureMapping::TYPE::srfp_mapping, + // m_mesh_xform has no meaning and is ignored by operator== and operator!=. ON_Xform m_mesh_xform = ON_Xform::IdentityTransformation; /* @@ -3136,11 +3348,19 @@ public: /* Returns: - A sha1 hash the identifies the mapping tag. + A sha1 hash of the m_mapping_id, m_mapping_type, m_mapping_crc and m_mesh_xform + the uniquely identifies the mapping tag but can be used where hashes are more + convenient. */ const ON_SHA1_Hash Hash() const; }; +ON_DECL +bool operator==(const ON_MappingTag& lhs, const ON_MappingTag& rhs); + +ON_DECL +bool operator!=(const ON_MappingTag& lhs, const ON_MappingTag& rhs); + class ON_CLASS ON_TextureCoordinates { public: @@ -3591,8 +3811,60 @@ Returns: bool HasTextureCoordinates() const; bool HasSurfaceParameters() const; bool HasPrincipalCurvatures() const; + + /// + /// If this mesh has per vertex colors set in the m_C[] array, then true is returned. + /// Otherwise false is returned. + /// bool HasVertexColors() const; + /// + /// + /// If this mesh has per vertex colors set in the m_C[] array and + /// color_tag = m_Ctag, then true is returned. + /// Otherwise false is returned. + /// + bool HasVertexColors( + ON_MappingTag color_tag + ) const; + + void ClearVertexColors(); + + /// + /// + /// + /// + /// + /// + /// + /// When in doubt, use ON_MappingTag::DraftAngleColorHueRangeDefault. + /// + /// + bool SetDraftAngleColorAnalysisColors( + bool bLazy, + ON_3dVector up, + ON_Interval draft_angle_range_in_radians, + ON_Interval hue_range_in_radians + ); + + + /// + /// + /// + /// + /// + /// + /// + /// When in doubt, use ON_MappingTag::CurvatureColorHueRangeDefault. + /// + /// + bool SetCurvatureColorAnalysisColors( + bool bLazy, + const ON::curvature_style kappa_style, + ON_Interval kappa_range, + ON_Interval hue_range_in_radians + ); + /* Returns: True if the mesh has ngons. diff --git a/opennurbs_plane.cpp b/opennurbs_plane.cpp index 8ead710e..bffb4776 100644 --- a/opennurbs_plane.cpp +++ b/opennurbs_plane.cpp @@ -360,6 +360,9 @@ bool ON_Plane::IsValid() const double x = plane_equation.ValueAt(origin); + if (ON_IS_NAN(x)) + return false; + if ( fabs(x) > ON_ZERO_TOLERANCE ) { double tol = fabs(origin.MaximumCoordinate()) + fabs(plane_equation.d); @@ -392,6 +395,23 @@ bool ON_Plane::IsValid() const return true; } +void ON_Plane::Dump(class ON_TextLog& text_log) const +{ + text_log.Print("plane equation: "); + plane_equation.Dump(text_log); + text_log.PrintNewLine(); + text_log.PushIndent(); + text_log.Print("xaxis="); + text_log.Print(xaxis); + text_log.Print(", yaxis="); + text_log.Print(yaxis); + text_log.Print(", zaxis="); + text_log.Print(zaxis); + text_log.Print(", origin="); + text_log.Print(origin); + text_log.PrintNewLine(); + text_log.PopIndent(); +} bool ON_Plane::Transform( const ON_Xform& xform ) { diff --git a/opennurbs_plane.h b/opennurbs_plane.h index 6b71c251..fbf2a7b4 100644 --- a/opennurbs_plane.h +++ b/opennurbs_plane.h @@ -273,6 +273,8 @@ See Also: */ bool IsValid() const; + void Dump(class ON_TextLog&) const; + /* Returns: Plane origin. diff --git a/opennurbs_point.cpp b/opennurbs_point.cpp index e45b5388..9cf726a1 100644 --- a/opennurbs_point.cpp +++ b/opennurbs_point.cpp @@ -585,6 +585,64 @@ double ON_Interval::ParameterAt(double x) const return (ON_IS_VALID(x) ? ((1.0-x)*m_t[0] + x*m_t[1]) : ON_UNSET_VALUE); } +double ON_Interval::ClampedParameterAt( + double x +) const +{ + if (ON_IS_VALID(x) && ON_IS_VALID(m_t[0]) && ON_IS_VALID(m_t[1])) + { + + if (x <= 0.0) + return m_t[0]; + if (x >= 1.0) + return m_t[1]; + if (m_t[0] == m_t[1]) + return m_t[0]; // no fuzz from a linear combination + return ((1.0 - x) * m_t[0] + x * m_t[1]); + } + + return ON_DBL_QNAN; +} + +double ON_Interval::ClampedNormalizedParameterAt( + double interval_parameter +) const +{ + if (ON_IS_VALID(interval_parameter) && ON_IS_VALID(m_t[0]) && ON_IS_VALID(m_t[1])) + { + if (m_t[0] < m_t[1]) + { + // this is an increasing interval + if (interval_parameter <= m_t[0]) + return 0.0; + if (interval_parameter >= m_t[1]) + return 1.0; + } + else if (m_t[0] > m_t[1]) + { + // this is a decreasing interval + if (interval_parameter >= m_t[0]) + return 0.0; + if (interval_parameter <= m_t[1]) + return 1.0; + } + else + { + // this is a singleton interval + if (interval_parameter < m_t[0]) + return 0.0; + if (interval_parameter > m_t[1]) + return 1.0; + return 0.5; + } + + // the interval_parameter is strictly between m_t[0] and m_t[1] + return (interval_parameter - m_t[0]) / (m_t[1] - m_t[0]); + } + + return ON_DBL_QNAN; +} + ON_Interval ON_Interval::ParameterAt(ON_Interval x) const { return ON_Interval( ParameterAt(x[0]), ParameterAt(x[1]) ); diff --git a/opennurbs_point.h b/opennurbs_point.h index 81758799..24041739 100644 --- a/opennurbs_point.h +++ b/opennurbs_point.h @@ -87,23 +87,58 @@ public: double t1 ); - /* - Description: - Convert normalized parameter to interval value, or pair of values. - Parameters: - normalized_parameter - [in] - Returns: - Interval parameter - min*(1.0-normalized_parameter) + max*normalized_parameter - See Also: - ON_Interval::NormalizedParameterAt - */ + /// + /// Convert a normalized parameter to an interval value. + /// The interval can be increasing, decreasing, or a singleton. + /// + /// + /// The normalized parameter can have any value. + /// + /// + /// a*(1.0-normalized_parameter) + b*normalized_parameter + /// where a = the value at the beginning of this interval + /// and b = the value at the end of this interval. + /// double ParameterAt ( double normalized_parameter ) const; + + /// + /// Convert a a pair of normalized parameter values to + /// a pair of interval values. + /// This interval can be increasing, decreasing, or a singleton. + /// + /// + /// The normalized parameters can have any value. + /// + /// + /// a*(1.0-normalized_parameter) + b*normalized_parameter + /// where a = the value at the beginning of this interval + /// and b = the value at the end of this interval. ON_Interval ParameterAt ( ON_Interval normalized_interval ) const; + + /// + /// Returns the interval's value at a clamped normalized parameter. + /// This interval may be increasing, decreasing, or a singleton. + /// + /// + /// normalized_parameter may have any value but it is clamped + /// to be between 0 and 1 before the corresponding interval + /// value is evaluated. + /// + /// + /// Set a = the value at the beginning of this interval and + /// b = the value at the end of this interval. + /// If a, b or normalized_parameter is unset or nan, ON_DBL_QNAN is returned. + /// If normalized_parameter <= 0.0, a is returned. + /// If normalized_parameter >= 1.0, b is returned. + /// Otherwise (1.0-normalized_parameter)*a + normalized_parameter*b is returned. + /// + double ClampedParameterAt( + double normalized_parameter + ) const; /* Description: @@ -123,6 +158,27 @@ public: ON_Interval interval_parameter ) const; + /// + /// Returns a clamped normalized parameter from an interval value. + /// This interval may be increasing, decreasing, or a singleton. + /// + /// + /// interval_parameter may have any value but it is clamped + /// to be in the intervaly before the normalized parameter is evaluated. + /// + /// + /// Set a = the value at the beginning of this interval and + /// b = the value at the end of this interval. + /// If a, b or interval_parameter is unset or nan, ON_DBL_QNAN is returned. + /// If interval_parameter is in this interval, the correxponding normalized + /// parameter is returned. + /// If interval_parameter is outside the interval, the normalized paramter for + /// the end closest to interval_parameter is retuend. + /// + double ClampedNormalizedParameterAt( + double interval_parameter + ) const; + double& operator[](int); // returns (index<=0) ? m_t[0] : m_t[1] double operator[](int) const; // returns (index<=0) ? m_t[0] : m_t[1] double& operator[](unsigned int); // returns (index<=0) ? m_t[0] : m_t[1] @@ -2193,6 +2249,11 @@ public: static const ON_SurfaceCurvature Nan; static const ON_SurfaceCurvature Zero; + /// + /// Value used to indicate a radius of curvature is infinite (1e300). + /// + static const double InfinteRadius; + public: double k1, k2; // principal curvatures @@ -2202,10 +2263,60 @@ public: bool IsUnset() const; public: + /// + /// The Gaussian curvature is k1*k2. + /// + /// The Gausian curvature. double GaussianCurvature() const; + + /// + /// The mean curvature is (k1+k2)/2. + /// + /// The signed mean curvature. double MeanCurvature() const; + + /// + /// The minimum radius of curvature is 1/max(fabs(k1),fabs(k2)). + /// Infinte radius values are returned as ON_SurfaceCurvature::InfinteRadius. + /// + /// + /// Minimum radius of curvature up to a maximum of 1e300. + /// If both k1 and k2 are zero, then 1e300 is returned. + /// double MinimumRadius() const; + + /// + /// If a principal curvature value is zero + /// or the principal curvatures have opposite signs, + /// then the maximum radius of curvature is infinite + /// and ON_SurfaceCurvature::InfinteRadius is returned. + /// Otherwise the maximum radius of curvature is 1/min(fabs(k1),fabs(k2)). + /// + /// + /// IF k1 and k2 are valid, the maximum radius of curvature is returned. + /// Otherwise ON_DBL_QNAN is returned. + /// double MaximumRadius() const; + + /// + /// Calculate one of the four typical curvature values associated + /// with the two principal curvatures and frequently used in false + /// color curvature analysis. + /// + /// + /// Specifies which type curvature (Gaussian, mean, ...) value to calculate from the principal curvatures. + /// The Gausian curvature can be positive or negative. The other curvatures are are >= 0. + /// In particular, ON::curvature_style::mean_curvature return fabs(this->MeanCurvature()). + /// + /// + /// If kappa_style and the principal curvatures are valid, the specified + /// type of curvature value is returned. + /// Infinte radii are returned as ON_SurfaceCurvature::InfinteRadius. + /// Otherwise ON_DBL_QNAN is returned. + /// + double KappaValue(ON::curvature_style kappa_style) const; + + }; diff --git a/opennurbs_public_version.h b/opennurbs_public_version.h index 52542502..54e6365e 100644 --- a/opennurbs_public_version.h +++ b/opennurbs_public_version.h @@ -15,7 +15,7 @@ // #define RMA_VERSION_YEAR 2023 #define RMA_VERSION_MONTH 8 -#define RMA_VERSION_DATE 4 +#define RMA_VERSION_DATE 21 #define RMA_VERSION_HOUR 4 #define RMA_VERSION_MINUTE 30 @@ -35,8 +35,8 @@ // 3 = build system release build #define RMA_VERSION_BRANCH 0 -#define VERSION_WITH_COMMAS 8,0,23216,4300 -#define VERSION_WITH_PERIODS 8.0.23216.04300 +#define VERSION_WITH_COMMAS 8,0,23233,4300 +#define VERSION_WITH_PERIODS 8.0.23233.04300 #define COPYRIGHT "Copyright (C) 1993-2023, Robert McNeel & Associates. All Rights Reserved." #define SPECIAL_BUILD_DESCRIPTION "Public OpenNURBS C++ 3dm file IO library." @@ -47,8 +47,8 @@ #define RMA_VERSION_NUMBER_SR_STRING "SR0" #define RMA_VERSION_NUMBER_SR_WSTRING L"SR0" -#define RMA_VERSION_WITH_PERIODS_STRING "8.0.23216.04300" -#define RMA_VERSION_WITH_PERIODS_WSTRING L"8.0.23216.04300" +#define RMA_VERSION_WITH_PERIODS_STRING "8.0.23233.04300" +#define RMA_VERSION_WITH_PERIODS_WSTRING L"8.0.23233.04300" diff --git a/opennurbs_sha1.cpp b/opennurbs_sha1.cpp index faad5155..afe72cd6 100644 --- a/opennurbs_sha1.cpp +++ b/opennurbs_sha1.cpp @@ -209,6 +209,11 @@ bool ON_SHA1_Hash::IsZeroDigentOrEmptyContentHash() const return IsZeroDigestOrEmptyContentHash(); } +ON__UINT32 ON_SHA1_Hash::CRC32(ON__UINT32 current_remainder) const +{ + return ON_CRC32(current_remainder, sizeof(m_digest) / sizeof(m_digest[0]), m_digest); +} + int ON_SHA1_Hash::Compare( const ON_SHA1_Hash& a, diff --git a/opennurbs_sha1.h b/opennurbs_sha1.h index 7883ef2c..d54bc4bb 100644 --- a/opennurbs_sha1.h +++ b/opennurbs_sha1.h @@ -276,6 +276,18 @@ public: */ bool IsSet() const; + /// + /// Calculating a SHA1 hash is faster than calculating a CRC on the same information. + /// This function calculates the ON_CRC value of the 20 byte digest. + /// Calculating a sha1 hash and then using CRC32(0) is an excellent and efficient way + /// to get a high quality 4 byte CRC. + /// + /// + /// Nonzero values are rare in this context. When in doubt, pass 0. + /// + /// ON_CRC32(seed, 20, m_digest) + ON__UINT32 CRC32(ON__UINT32 current_remainder) const; + ON__UINT8 m_digest[20]; }; diff --git a/opennurbs_skylight.cpp b/opennurbs_skylight.cpp index 1ae43acc..ef50fd14 100644 --- a/opennurbs_skylight.cpp +++ b/opennurbs_skylight.cpp @@ -22,6 +22,9 @@ #error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs #endif +// ShadowIntensity in the Sun and Skylight are currently unused. The only ShadowIntensity that's actually +// used is the one in the lights. See [SHADOW_INTENSITY_UNUSED] + class ON_Skylight::CImpl : public ON_InternalXMLImpl { public: @@ -92,11 +95,13 @@ void ON_Skylight::SetEnabled(bool b) double ON_Skylight::ShadowIntensity(void) const { + // ShadowIntensity is currently unused. See [SHADOW_INTENSITY_UNUSED] return m_impl->GetParameter(XMLPath(), ON_RDK_SUN_SKYLIGHT_SHADOW_INTENSITY, 1.0).AsDouble(); } void ON_Skylight::SetShadowIntensity(double d) { + // ShadowIntensity is currently unused. See [SHADOW_INTENSITY_UNUSED] m_impl->SetParameter(XMLPath(), ON_RDK_SUN_SKYLIGHT_SHADOW_INTENSITY, d); } diff --git a/opennurbs_skylight.h b/opennurbs_skylight.h index 11a3f027..e88af3cd 100644 --- a/opennurbs_skylight.h +++ b/opennurbs_skylight.h @@ -33,10 +33,10 @@ public: // Set the skylight enabled state. virtual void SetEnabled(bool b); - // Returns the skylight shadow intensity. This is unused at present. + // Returns the skylight shadow intensity. This is currently unused. virtual double ShadowIntensity(void) const; - // Set the skylight shadow intensity. This is unused at present. + // Set the skylight shadow intensity. This is currently unused. virtual void SetShadowIntensity(double d); // Emergency virtual function for future expansion. diff --git a/opennurbs_statics.cpp b/opennurbs_statics.cpp index f6bfbd50..c57c9d3b 100644 --- a/opennurbs_statics.cpp +++ b/opennurbs_statics.cpp @@ -22,12 +22,12 @@ const ON_ErrorEvent ON_ErrorEvent::Unset; -static unsigned int ON_LibraryStatusInit() +static unsigned int Internal_ON_LibraryStatusInit() { return 0; } -unsigned int ON::m_opennurbs_library_status = ON_LibraryStatusInit(); +unsigned int ON::m_opennurbs_library_status = Internal_ON_LibraryStatusInit(); unsigned int ON_MemoryAllocationTracking::m_g_stack_depth = 0; int ON_MemoryAllocationTracking::m_g_crt_dbg_flag0 = 0; @@ -140,7 +140,7 @@ to indicate invalid operations. SH - http://steve.hollasch.net/cgindex/coding/ieeefloat.html Intel - */ -static double ON__dblinithelper(int i) +static double Internal_ON__dblinithelper(int i) { // called twice - performance is not important union @@ -221,7 +221,7 @@ static double ON__dblinithelper(int i) return u.x; } -static float ON__fltinithelper(int i) +static float Internal_ON__fltinithelper(int i) { // called twice - performance is not important union @@ -283,13 +283,13 @@ static float ON__fltinithelper(int i) return u.x; } -const double ON_DBL_QNAN = ON__dblinithelper(1); -const double ON_DBL_PINF = ON__dblinithelper(2); -const double ON_DBL_NINF = -ON__dblinithelper(2); +const double ON_DBL_QNAN = Internal_ON__dblinithelper(1); +const double ON_DBL_PINF = Internal_ON__dblinithelper(2); +const double ON_DBL_NINF = -Internal_ON__dblinithelper(2); -const float ON_FLT_QNAN = ON__fltinithelper(1); -const float ON_FLT_PINF = ON__fltinithelper(2); -const float ON_FLT_NINF = -ON__fltinithelper(2); +const float ON_FLT_QNAN = Internal_ON__fltinithelper(1); +const float ON_FLT_PINF = Internal_ON__fltinithelper(2); +const float ON_FLT_NINF = -Internal_ON__fltinithelper(2); // It is critical that ON_ModelComponent::Internal_RuntimeSerialNumberGenerator // be constructed before any instance of a class derived from ON_ModelComponent. @@ -524,20 +524,20 @@ const ON_CheckSum ON_CheckSum::UnsetCheckSum; const ONX_ErrorCounter ONX_ErrorCounter::Zero; -static ON_MD5_Hash ON_MD5_Hash_EmptyContentHash() +static ON_MD5_Hash Internal_ON_MD5_Hash_EmptyContentHash() { ON_MD5 md5; return md5.Hash(); } -const ON_MD5_Hash ON_MD5_Hash::EmptyContentHash = ON_MD5_Hash_EmptyContentHash(); +const ON_MD5_Hash ON_MD5_Hash::EmptyContentHash = Internal_ON_MD5_Hash_EmptyContentHash(); const ON_MD5_Hash ON_MD5_Hash::ZeroDigest; -static ON_SHA1_Hash ON_SHA1_Hash_EmptyContentHash() +static ON_SHA1_Hash Internal_ON_SHA1_Hash_EmptyContentHash() { ON_SHA1 sha1; return sha1.Hash(); } -const ON_SHA1_Hash ON_SHA1_Hash::EmptyContentHash = ON_SHA1_Hash_EmptyContentHash(); +const ON_SHA1_Hash ON_SHA1_Hash::EmptyContentHash = Internal_ON_SHA1_Hash_EmptyContentHash(); const ON_SHA1_Hash ON_SHA1_Hash::ZeroDigest; const ONX_ModelTest ONX_ModelTest::Unset; @@ -621,7 +621,7 @@ const ON_3dmProperties ON_3dmProperties::Empty; -static ON_Xform ON_Xform_Init(double x, bool bDiagonal) +static ON_Xform Internal_ON_Xform_Init(double x, bool bDiagonal) { ON_Xform xform; memset(&xform, 0, sizeof(xform)); @@ -642,13 +642,14 @@ static ON_Xform ON_Xform_Init(double x, bool bDiagonal) return xform; } -const ON_Xform ON_Xform::IdentityTransformation = ON_Xform_Init(1.0, true); -const ON_Xform ON_Xform::ZeroTransformation = ON_Xform_Init(0.0, true); +const ON_Xform ON_Xform::IdentityTransformation = Internal_ON_Xform_Init(1.0, true); +const ON_Xform ON_Xform::ZeroTransformation = Internal_ON_Xform_Init(0.0, true); -const ON_Xform ON_Xform::Zero4x4 = ON_Xform_Init(0.0, false); -const ON_Xform ON_Xform::Unset = ON_Xform_Init(ON_UNSET_VALUE, false); -const ON_Xform ON_Xform::Nan = ON_Xform_Init(ON_DBL_QNAN, false); +const ON_Xform ON_Xform::Zero4x4 = Internal_ON_Xform_Init(0.0, false); +const ON_Xform ON_Xform::Unset = Internal_ON_Xform_Init(ON_UNSET_VALUE, false); +const ON_Xform ON_Xform::Nan = Internal_ON_Xform_Init(ON_DBL_QNAN, false); +const double ON_SurfaceCurvature::InfinteRadius = 1e300; const ON_SurfaceCurvature ON_SurfaceCurvature::Nan = ON_SurfaceCurvature::CreateFromPrincipalCurvatures(ON_DBL_QNAN, ON_DBL_QNAN); const ON_SurfaceCurvature ON_SurfaceCurvature::Zero = ON_SurfaceCurvature::CreateFromPrincipalCurvatures(0.0, 0.0); @@ -721,7 +722,7 @@ const ON_UUID ON_Symmetry::RotateId = const ON_UUID ON_Symmetry::ReflectAndRotateId = { 0x9133927d, 0x5a4e, 0x4ddd, { 0x99, 0x24, 0xef, 0x3a, 0x63, 0x60, 0xc1, 0x9a } }; -static ON_BoundingBox BoundingBoxInit(double x) +static ON_BoundingBox Internal_BoundingBoxInit(double x) { ON_BoundingBox bbox; bbox.m_min.x = x; @@ -733,8 +734,8 @@ static ON_BoundingBox BoundingBoxInit(double x) return bbox; } const ON_BoundingBox ON_BoundingBox::EmptyBoundingBox; -const ON_BoundingBox ON_BoundingBox::UnsetBoundingBox = BoundingBoxInit(ON_UNSET_VALUE); -const ON_BoundingBox ON_BoundingBox::NanBoundingBox = BoundingBoxInit(ON_DBL_QNAN); +const ON_BoundingBox ON_BoundingBox::UnsetBoundingBox = Internal_BoundingBoxInit(ON_UNSET_VALUE); +const ON_BoundingBox ON_BoundingBox::NanBoundingBox = Internal_BoundingBoxInit(ON_DBL_QNAN); const ON_UnitSystem ON_UnitSystem::None(ON::LengthUnitSystem::None); const ON_UnitSystem ON_UnitSystem::Angstroms(ON::LengthUnitSystem::Angstroms); @@ -869,16 +870,16 @@ const ON_Locale ON_Locale::InvariantCulture = ON_Locale::FromWindowsLCID(ON_Loca ON_Locale ON_Locale::m_CurrentCulture = ON_Locale::Ordinal; const ON_Locale& ON_Locale::CurrentCulture = ON_Locale::m_CurrentCulture; -static ON_ClippingRegionPoints ON_ClippingRegionPoints_EmptyInit() +static ON_ClippingRegionPoints Internal_ON_ClippingRegionPoints_EmptyInit() { ON_ClippingRegionPoints empty_clip_points; memset(&empty_clip_points, 0, sizeof(empty_clip_points)); return empty_clip_points; } -const ON_ClippingRegionPoints ON_ClippingRegionPoints::Empty = ON_ClippingRegionPoints_EmptyInit(); +const ON_ClippingRegionPoints ON_ClippingRegionPoints::Empty = Internal_ON_ClippingRegionPoints_EmptyInit(); -static ON_PickPoint ON_PickPoint_UnsetInit() +static ON_PickPoint Internal_ON_PickPoint_UnsetInit() { ON_PickPoint unset_pick_point; double* p = unset_pick_point.m_t; @@ -888,7 +889,7 @@ static ON_PickPoint ON_PickPoint_UnsetInit() return unset_pick_point; } -const ON_PickPoint ON_PickPoint::Unset = ON_PickPoint_UnsetInit(); +const ON_PickPoint ON_PickPoint::Unset = Internal_ON_PickPoint_UnsetInit(); const ON_Color ON_Color::UnsetColor(ON_UNSET_COLOR); const ON_Color ON_Color::Black(0, 0, 0); @@ -945,7 +946,7 @@ static ON_Plane ON_Plane_UnsetPlane() const ON_Plane ON_Plane::UnsetPlane(ON_Plane_UnsetPlane()); -static ON_Plane ON_Plane_NanPlane() +static ON_Plane Internal_ON_Plane_NanPlane() { ON_Plane nan_plane; nan_plane.xaxis = ON_3dVector::NanVector; @@ -955,7 +956,7 @@ static ON_Plane ON_Plane_NanPlane() nan_plane.plane_equation = ON_PlaneEquation::NanPlaneEquation; return nan_plane; } -const ON_Plane ON_Plane::NanPlane(ON_Plane_NanPlane()); +const ON_Plane ON_Plane::NanPlane(Internal_ON_Plane_NanPlane()); // ON_SubDDisplayParameters statics before ON_MeshParamters statics const ON_SubDDisplayParameters ON_SubDDisplayParameters::Empty; @@ -1170,7 +1171,7 @@ bool ON_MeshParameters_AreValid() return true; } -const static bool ON_MeshParameters_AreValid_ = ON_MeshParameters_AreValid(); +const static bool Internal_ON_MeshParameters_AreValid_ = ON_MeshParameters_AreValid(); const ON_3dmUnitsAndTolerances ON_3dmUnitsAndTolerances::Millimeters; @@ -1456,7 +1457,7 @@ const ON_3dmObjectAttributes ON_3dmObjectAttributes::Unset; const ON_3dmObjectAttributes ON_3dmObjectAttributes::DefaultAttributes; -static const ON_ModelComponentTypeIterator ON_ModelComponentIterator_Init( +static const ON_ModelComponentTypeIterator Internal_ON_ModelComponentIterator_Init( int list_selector ) { @@ -1530,8 +1531,8 @@ static const ON_ModelComponentTypeIterator ON_ModelComponentIterator_Init( return ON_ModelComponentTypeIterator(0, nullptr); } -const ON_ModelComponentTypeIterator ON_ModelComponentTypeIterator::ExplicitComponentTypes(ON_ModelComponentIterator_Init(1)); -const ON_ModelComponentTypeIterator ON_ModelComponentTypeIterator::TableComponentTypes(ON_ModelComponentIterator_Init(2)); +const ON_ModelComponentTypeIterator ON_ModelComponentTypeIterator::ExplicitComponentTypes(Internal_ON_ModelComponentIterator_Init(1)); +const ON_ModelComponentTypeIterator ON_ModelComponentTypeIterator::TableComponentTypes(Internal_ON_ModelComponentIterator_Init(2)); const ON_ModelComponent ON_ModelComponent::Unset(ON_ModelComponent::Type::Unset, (ON__UINT64) 0); @@ -1607,13 +1608,13 @@ const ON_Material ON_Material::DefaultLockedObject(Internal_SystemMaterialInit(- const ON_TextureMapping ON_TextureMapping::Unset; -static ON_TextureMapping SurfaceParameterTextureMappingInitializer() -{ - //// {B988A6C2-61A6-45a7-AAEE-9AED7EF4E316} - const ON_UUID srfp_mapping_id = { 0xb988a6c2, 0x61a6, 0x45a7,{ 0xaa, 0xee, 0x9a, 0xed, 0x7e, 0xf4, 0xe3, 0x16 } }; +// {B988A6C2-61A6-45a7-AAEE-9AED7EF4E316} +const ON_UUID ON_TextureMapping::SurfaceParameterTextureMappingId = { 0xb988a6c2, 0x61a6, 0x45a7,{ 0xaa, 0xee, 0x9a, 0xed, 0x7e, 0xf4, 0xe3, 0x16 } }; +static ON_TextureMapping Internal_SurfaceParameterTextureMappingInitializer() +{ ON_TextureMapping tm; - tm.SetId(srfp_mapping_id); + tm.SetId(ON_TextureMapping::SurfaceParameterTextureMappingId); tm.SetIndex(-1); // name = empty @@ -1621,11 +1622,32 @@ static ON_TextureMapping SurfaceParameterTextureMappingInitializer() return tm; } -const ON_TextureMapping ON_TextureMapping::SurfaceParameterTextureMapping(SurfaceParameterTextureMappingInitializer()); +const ON_TextureMapping ON_TextureMapping::SurfaceParameterTextureMapping(Internal_SurfaceParameterTextureMappingInitializer()); const ON_MappingTag ON_MappingTag::Unset; const ON_MappingTag ON_MappingTag::SurfaceParameterMapping(ON_TextureMapping::SurfaceParameterTextureMapping,nullptr); +// {639E9144-1C1A-4bba-8248-D330F50D7B69} +// RHINO_CURVATURE_COLOR_ANALYSIS_MODE_ID and ON_MappingTag::CurvatureColorAnalysisId +// are identical ids and must never be changed. +const ON_UUID ON_MappingTag::CurvatureColorAnalysisId = +{ 0x639e9144, 0x1c1a, 0x4bba, { 0x82, 0x48, 0xd3, 0x30, 0xf5, 0xd, 0x7b, 0x69 } }; + +// Hue range used by the Rhino surface curvature color analysis. +// Currently red to blue. +const ON_Interval ON_MappingTag::CurvatureColorHueRangeDefault(0.0, 4.0 * ON_PI / 3.0); + + +// {F08463F4-22E2-4cf1-B810-F01925446D71} +// RHINO_DRAFT_ANGLE_ANALYSIS_MODE_ID and ON_MappingTag::DraftAngleColorAnalysisId +// are identical ids and must never be changed. +const ON_UUID ON_MappingTag::DraftAngleColorAnalysisId = +{ 0xf08463f4, 0x22e2, 0x4cf1, { 0xb8, 0x10, 0xf0, 0x19, 0x25, 0x44, 0x6d, 0x71 } }; + +// Hue range used by the Rhino draft angle color analysis. +// Currently red to blue. +const ON_Interval ON_MappingTag::DraftAngleColorHueRangeDefault(0.0, 4.0 * ON_PI / 3.0); + const ON_LinetypeSegment ON_LinetypeSegment::Unset; const ON_LinetypeSegment ON_LinetypeSegment::OneMillimeterLine(1.0, ON_LinetypeSegment::eSegType::stLine); @@ -1819,7 +1841,7 @@ const ON_Linetype ON_Linetype::Center(Internal_BuiltInLinePattern(-7)); const ON_Linetype ON_Linetype::Border(Internal_BuiltInLinePattern(-8)); const ON_Linetype ON_Linetype::Dots(Internal_BuiltInLinePattern(-9)); -static void TextStyleInit( +static void Internal_TextStyleInit( const wchar_t* name, ON_UUID id, int index, @@ -1849,7 +1871,7 @@ static void TextStyleInit( const ON_Layer ON_Layer::Unset; -static ON_Layer ON_Layer_Default() +static ON_Layer Internal_ON_Layer_Default() { // {061DF99E-2EF8-4A3F-8F2D-4B123A166089} const ON_UUID id = { 0x61df99e, 0x2ef8, 0x4a3f,{ 0x8f, 0x2d, 0x4b, 0x12, 0x3a, 0x16, 0x60, 0x89 } }; @@ -1858,52 +1880,52 @@ static ON_Layer ON_Layer_Default() Internal_SystemModelComponentInit(id, -1, L"Default", layer); return layer; } -const ON_Layer ON_Layer::Default = ON_Layer_Default(); +const ON_Layer ON_Layer::Default = Internal_ON_Layer_Default(); -static ON_TextStyle UnsetTextStyle() +static ON_TextStyle Internal_UnsetTextStyle() { ON_TextStyle text_style; - TextStyleInit(nullptr, ON_nil_uuid, 0, nullptr, text_style); + Internal_TextStyleInit(nullptr, ON_nil_uuid, 0, nullptr, text_style); return text_style; } -static ON_TextStyle DefaultTextStyle() +static ON_TextStyle Internal_DefaultTextStyle() { // {8F3A5848-7741-4AA9-B6A0-FA4F76C9D918} const ON_UUID default_text_style_id = { 0x8f3a5848, 0x7741, 0x4aa9,{ 0xb6, 0xa0, 0xfa, 0x4f, 0x76, 0xc9, 0xd9, 0x18 } }; ON_TextStyle text_style; - TextStyleInit(L"Default", default_text_style_id, -1, &ON_Font::Default, text_style); + Internal_TextStyleInit(L"Default", default_text_style_id, -1, &ON_Font::Default, text_style); return text_style; } -static ON_TextStyle ByLayerTextStyle() +static ON_TextStyle Internal_ByLayerTextStyle() { // {DA800C9A-EB00-4251-8237-615017F3BB67} const ON_UUID ByLayer_text_style_id = { 0xda800c9a, 0xeb00, 0x4251,{ 0x82, 0x37, 0x61, 0x50, 0x17, 0xf3, 0xbb, 0x67 } }; ON_TextStyle text_style; - TextStyleInit(L"By Layer", ByLayer_text_style_id, -2, nullptr, text_style); + Internal_TextStyleInit(L"By Layer", ByLayer_text_style_id, -2, nullptr, text_style); return text_style; } -static ON_TextStyle ByParentTextStyle() +static ON_TextStyle Internal_ByParentTextStyle() { // {4D82AFFA-0433-4CE0-92C8-BD328E23C49F} const ON_UUID ByParent_text_style_id = { 0x4d82affa, 0x433, 0x4ce0,{ 0x92, 0xc8, 0xbd, 0x32, 0x8e, 0x23, 0xc4, 0x9f } }; ON_TextStyle text_style; - TextStyleInit(L"By Parent", ByParent_text_style_id, -3, nullptr, text_style); + Internal_TextStyleInit(L"By Parent", ByParent_text_style_id, -3, nullptr, text_style); return text_style; } -const ON_TextStyle ON_TextStyle::Unset(UnsetTextStyle()); -const ON_TextStyle ON_TextStyle::Default(DefaultTextStyle()); -const ON_TextStyle ON_TextStyle::ByLayer(ByLayerTextStyle()); -const ON_TextStyle ON_TextStyle::ByParent(ByParentTextStyle()); +const ON_TextStyle ON_TextStyle::Unset(Internal_UnsetTextStyle()); +const ON_TextStyle ON_TextStyle::Default(Internal_DefaultTextStyle()); +const ON_TextStyle ON_TextStyle::ByLayer(Internal_ByLayerTextStyle()); +const ON_TextStyle ON_TextStyle::ByParent(Internal_ByParentTextStyle()); const ON_TextMask ON_TextMask::None; @@ -1923,7 +1945,7 @@ const ON_TextMask ON_TextMask::None; const ON_FontFaceQuartet ON_FontFaceQuartet::Empty; -static void DimStyleInit( +static void Internal_DimStyleInit( const wchar_t* name, int index, ON_UUID id, @@ -1949,7 +1971,7 @@ static void Internal_SystemDimStyleFinalize( // Static DimStyle definitions -static void DimStyleDefaultInit(ON_DimStyle& ds) +static void Internal_DimStyleDefaultInit(ON_DimStyle& ds) { ds.SetExtExtension (0.5); ds.SetExtOffset (0.5); @@ -2051,9 +2073,9 @@ static void DimStyleDefaultInit(ON_DimStyle& ds) ds.SetTextUnderlined (false); } -static void DimStyleMillimeterArchitecturalInit(ON_DimStyle& ds) +static void Internal_DimStyleMillimeterArchitecturalInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (1.0); ds.SetArrowSize (3.0); ds.SetLeaderArrowSize (3.0); @@ -2072,9 +2094,9 @@ static void DimStyleMillimeterArchitecturalInit(ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Millimeters); } -static void DimStyleMillimeterLargeInit(ON_DimStyle& ds) +static void Internal_DimStyleMillimeterLargeInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (1.0); ds.SetArrowSize (3.5); ds.SetLeaderArrowSize (3.5); @@ -2092,9 +2114,9 @@ static void DimStyleMillimeterLargeInit(ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Millimeters); } -static void DimStyleMillimeterSmallInit (ON_DimStyle& ds) +static void Internal_DimStyleMillimeterSmallInit (ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (1.0); ds.SetArrowSize (3.0); ds.SetLeaderArrowSize (3.0); @@ -2110,9 +2132,9 @@ static void DimStyleMillimeterSmallInit (ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Millimeters); } -static void DimStyleInchDecimalInit(ON_DimStyle& ds) +static void Internal_DimStyleInchDecimalInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (0.125); ds.SetExtOffset (0.0625); ds.SetArrowSize (0.125); @@ -2129,9 +2151,9 @@ static void DimStyleInchDecimalInit(ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Inches); } -static void DimStyleInchFractionalInit(ON_DimStyle& ds) +static void Internal_DimStyleInchFractionalInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (0.125); ds.SetExtOffset (0.0625); ds.SetArrowSize (0.1); @@ -2152,9 +2174,9 @@ static void DimStyleInchFractionalInit(ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Inches); } -static void DimStyleFootInchArchitecturalInit(ON_DimStyle& ds) +static void Internal_DimStyleFootInchArchitecturalInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (0.125); ds.SetExtOffset (0.0625); ds.SetArrowSize (0.1); @@ -2175,9 +2197,9 @@ static void DimStyleFootInchArchitecturalInit(ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Inches); } -static void DimStyleFeetDecimalInit(ON_DimStyle& ds) +static void Internal_DimStyleFeetDecimalInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (0.125); ds.SetExtOffset (0.0625); ds.SetArrowSize (0.125); @@ -2193,9 +2215,9 @@ static void DimStyleFeetDecimalInit(ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Inches); } -static void DimStyleModelUnitsDecimalInit(ON_DimStyle& ds) +static void Internal_DimStyleModelUnitsDecimalInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (0.125); ds.SetExtOffset (0.0625); ds.SetArrowSize (0.125); @@ -2210,18 +2232,18 @@ static void DimStyleModelUnitsDecimalInit(ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Inches); } -static void DimStyleFeetEngraveInit(ON_DimStyle& ds) +static void Internal_DimStyleFeetEngraveInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetDimensionLengthDisplay (ON_DimStyle::LengthDisplay::FeetDecimal); ds.SetTextVerticalAlignment (ON::TextVerticalAlignment::Bottom); ds.SetDimScale (12.0); ds.SetUnitSystem (ON::LengthUnitSystem::Inches); } -static void DimStyleMillimeterEngraveInit(ON_DimStyle& ds) +static void Internal_DimStyleMillimeterEngraveInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetExtExtension (1.5); ds.SetExtOffset (1.5); ds.SetArrowSize (3.0); @@ -2237,9 +2259,9 @@ static void DimStyleMillimeterEngraveInit(ON_DimStyle& ds) ds.SetUnitSystem (ON::LengthUnitSystem::Millimeters); } -static void DimStyleModelUnitsEngraveInit(ON_DimStyle& ds) +static void Internal_DimStyleModelUnitsEngraveInit(ON_DimStyle& ds) { - DimStyleDefaultInit(ds); + Internal_DimStyleDefaultInit(ds); ds.SetAlternateDimensionLengthDisplay (ON_DimStyle::LengthDisplay::Millmeters); ds.SetToleranceHeightScale (1.0); ds.SetTextVerticalAlignment (ON::TextVerticalAlignment::Bottom); @@ -2248,123 +2270,123 @@ static void DimStyleModelUnitsEngraveInit(ON_DimStyle& ds) } -static ON_DimStyle DimStyleDefault() +static ON_DimStyle Internal_DimStyleDefault() { const ON_UUID id = { 0x25b90869, 0x22, 0x4e04,{ 0xb4, 0x98, 0x98, 0xb4, 0x17, 0x5f, 0x65, 0xfd } }; ON_DimStyle dimstyle; - DimStyleInit(L"Default", -1, id, dimstyle); - DimStyleDefaultInit(dimstyle); + Internal_DimStyleInit(L"Default", -1, id, dimstyle); + Internal_DimStyleDefaultInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleInchDecimal() +static ON_DimStyle Internal_DimStyleInchDecimal() { const ON_UUID id = { 0x2105610c, 0xcfc7, 0x4473,{ 0xa5, 0x80, 0xc3, 0xd9, 0xc, 0xe8, 0xc7, 0xa3 } }; ON_DimStyle dimstyle; - DimStyleInit(L"Inch Decimal", -2, id, dimstyle); - DimStyleInchDecimalInit(dimstyle); + Internal_DimStyleInit(L"Inch Decimal", -2, id, dimstyle); + Internal_DimStyleInchDecimalInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleInchFractional() +static ON_DimStyle Internal_DimStyleInchFractional() { const ON_UUID id = { 0x6bcb1506, 0x699f, 0x445d,{ 0xa1, 0x22, 0x4f, 0xc7, 0x78, 0x2b, 0xc4, 0x86 } }; ON_DimStyle dimstyle; - DimStyleInit(L"Inch Fractional", -3, id, dimstyle); - DimStyleInchFractionalInit(dimstyle); + Internal_DimStyleInit(L"Inch Fractional", -3, id, dimstyle); + Internal_DimStyleInchFractionalInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleFootInchArchitectural() +static ON_DimStyle Internal_DimStyleFootInchArchitectural() { const ON_UUID id = { 0x50d6ef1b, 0xd1d0, 0x408a,{ 0x86, 0xc0, 0xee, 0x8b, 0x36, 0x8, 0x88, 0x3e } }; ON_DimStyle dimstyle; - DimStyleInit(L"Foot-Inch Architectural", -4, id, dimstyle); - DimStyleFootInchArchitecturalInit(dimstyle); + Internal_DimStyleInit(L"Foot-Inch Architectural", -4, id, dimstyle); + Internal_DimStyleFootInchArchitecturalInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleMillimeterSmall() +static ON_DimStyle Internal_DimStyleMillimeterSmall() { const ON_UUID id = { 0xdbe22573, 0x8cad, 0x4ced,{ 0x89, 0x47, 0x3, 0xa0, 0x48, 0xed, 0xde, 0x56 } }; ON_DimStyle dimstyle; - DimStyleInit(L"Millimeter Small", -5, id, dimstyle); - DimStyleMillimeterSmallInit(dimstyle); + Internal_DimStyleInit(L"Millimeter Small", -5, id, dimstyle); + Internal_DimStyleMillimeterSmallInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleMillimeterLarge() +static ON_DimStyle Internal_DimStyleMillimeterLarge() { const ON_UUID id = { 0xf7b30534, 0x773e, 0x45bc,{ 0x9d, 0x87, 0x9d, 0x14, 0x80, 0x9c, 0x96, 0x44 } }; ON_DimStyle dimstyle; - DimStyleInit(L"Millimeter Large", -6, id, dimstyle); - DimStyleMillimeterLargeInit(dimstyle); + Internal_DimStyleInit(L"Millimeter Large", -6, id, dimstyle); + Internal_DimStyleMillimeterLargeInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleMillimeterArchitectural() +static ON_DimStyle Internal_DimStyleMillimeterArchitectural() { const ON_UUID id = { 0xe5a4c08f, 0x23b3, 0x4033,{ 0x90, 0xb2, 0xfb, 0x31, 0xec, 0x45, 0x92, 0x9b } }; ON_DimStyle dimstyle; - DimStyleInit(L"Millimeter Architectural", -7, id, dimstyle); - DimStyleMillimeterArchitecturalInit(dimstyle); + Internal_DimStyleInit(L"Millimeter Architectural", -7, id, dimstyle); + Internal_DimStyleMillimeterArchitecturalInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleFeetDecimal() +static ON_DimStyle Internal_DimStyleFeetDecimal() { // {6F4B1840-8A12-4DE9-BF84-6A98B06C508D} const ON_UUID id = { 0x6f4b1840, 0x8a12, 0x4de9, { 0xbf, 0x84, 0x6a, 0x98, 0xb0, 0x6c, 0x50, 0x8d } }; ON_DimStyle dimstyle; - DimStyleInit(L"Feet Decimal", -8, id, dimstyle); - DimStyleFeetDecimalInit(dimstyle); + Internal_DimStyleInit(L"Feet Decimal", -8, id, dimstyle); + Internal_DimStyleFeetDecimalInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleModelUnitsDecimal() +static ON_DimStyle Internal_DimStyleModelUnitsDecimal() { const ON_UUID id = { 0x93a38bdf, 0x4c1c, 0x428c, { 0x8b, 0x97, 0x93, 0x59, 0xf1, 0xbd, 0xed, 0x17 } }; ON_DimStyle dimstyle; - DimStyleInit(L"Model Units Decimal", -9, id, dimstyle); - DimStyleModelUnitsDecimalInit(dimstyle); + Internal_DimStyleInit(L"Model Units Decimal", -9, id, dimstyle); + Internal_DimStyleModelUnitsDecimalInit(dimstyle); Internal_SystemDimStyleFinalize(dimstyle); return dimstyle; } -static ON_DimStyle DimStyleFeetEngrave() +static ON_DimStyle Internal_DimStyleFeetEngrave() { const ON_UUID id = { 0xc2d8846b, 0x918d, 0x4779, { 0x96, 0xec, 0x31, 0xb4, 0xe2, 0x75, 0xfb, 0x4e } }; ON_DimStyle dimstyle; - DimStyleInit(L"Feet Engrave", -10, id, dimstyle); - DimStyleFeetEngraveInit(dimstyle); + Internal_DimStyleInit(L"Feet Engrave", -10, id, dimstyle); + Internal_DimStyleFeetEngraveInit(dimstyle); const ON_Font* font = ON_Font::DefaultEngravingFont(); if (nullptr != font) dimstyle.SetFont(*font); @@ -2372,14 +2394,14 @@ static ON_DimStyle DimStyleFeetEngrave() return dimstyle; } -static ON_DimStyle DimStyleMillimeterEngrave() +static ON_DimStyle Internal_DimStyleMillimeterEngrave() { const ON_UUID id = { 0x741980ff, 0xde0f, 0x4ed7, { 0xaa, 0x6f, 0xee, 0x91, 0xb3, 0xbe, 0x96, 0xc6 } }; ON_DimStyle dimstyle; - DimStyleInit(L"Millimeter Engrave", -11, id, dimstyle); - DimStyleMillimeterEngraveInit(dimstyle); + Internal_DimStyleInit(L"Millimeter Engrave", -11, id, dimstyle); + Internal_DimStyleMillimeterEngraveInit(dimstyle); const ON_Font* font = ON_Font::DefaultEngravingFont(); if (nullptr != font) dimstyle.SetFont(*font); @@ -2387,14 +2409,14 @@ static ON_DimStyle DimStyleMillimeterEngrave() return dimstyle; } -static ON_DimStyle DimStyleModelUnitsEngrave() +static ON_DimStyle Internal_DimStyleModelUnitsEngrave() { const ON_UUID id = { 0x2cc3a895, 0x5389, 0x467e, { 0x9d, 0xbe, 0x3a, 0xca, 0xb4, 0x38, 0x60, 0xfa } }; ON_DimStyle dimstyle; - DimStyleInit(L"Model Units Engrave", -12, id, dimstyle); - DimStyleModelUnitsEngraveInit(dimstyle); + Internal_DimStyleInit(L"Model Units Engrave", -12, id, dimstyle); + Internal_DimStyleModelUnitsEngraveInit(dimstyle); const ON_Font* font = ON_Font::DefaultEngravingFont(); if (nullptr != font) dimstyle.SetFont(*font); @@ -2404,22 +2426,22 @@ static ON_DimStyle DimStyleModelUnitsEngrave() const ON_DimStyle ON_DimStyle::Unset; -const ON_DimStyle ON_DimStyle::Default(DimStyleDefault()); +const ON_DimStyle ON_DimStyle::Default(Internal_DimStyleDefault()); -const ON_DimStyle ON_DimStyle::DefaultInchDecimal(DimStyleInchDecimal()); -const ON_DimStyle ON_DimStyle::DefaultInchFractional(DimStyleInchFractional()); -const ON_DimStyle ON_DimStyle::DefaultFootInchArchitecture(DimStyleFootInchArchitectural()); +const ON_DimStyle ON_DimStyle::DefaultInchDecimal(Internal_DimStyleInchDecimal()); +const ON_DimStyle ON_DimStyle::DefaultInchFractional(Internal_DimStyleInchFractional()); +const ON_DimStyle ON_DimStyle::DefaultFootInchArchitecture(Internal_DimStyleFootInchArchitectural()); -const ON_DimStyle ON_DimStyle::DefaultMillimeterSmall(DimStyleMillimeterSmall()); -const ON_DimStyle ON_DimStyle::DefaultMillimeterLarge(DimStyleMillimeterLarge()); -const ON_DimStyle ON_DimStyle::DefaultMillimeterArchitecture(DimStyleMillimeterArchitectural()); +const ON_DimStyle ON_DimStyle::DefaultMillimeterSmall(Internal_DimStyleMillimeterSmall()); +const ON_DimStyle ON_DimStyle::DefaultMillimeterLarge(Internal_DimStyleMillimeterLarge()); +const ON_DimStyle ON_DimStyle::DefaultMillimeterArchitecture(Internal_DimStyleMillimeterArchitectural()); -const ON_DimStyle ON_DimStyle::DefaultFeetDecimal(DimStyleFeetDecimal()); -const ON_DimStyle ON_DimStyle::DefaultModelUnitsDecimal(DimStyleModelUnitsDecimal()); +const ON_DimStyle ON_DimStyle::DefaultFeetDecimal(Internal_DimStyleFeetDecimal()); +const ON_DimStyle ON_DimStyle::DefaultModelUnitsDecimal(Internal_DimStyleModelUnitsDecimal()); -const ON_DimStyle ON_DimStyle::DefaultFeetEngrave(DimStyleFeetEngrave()); -const ON_DimStyle ON_DimStyle::DefaultMillimeterEngrave(DimStyleMillimeterEngrave()); -const ON_DimStyle ON_DimStyle::DefaultModelUnitsEngrave(DimStyleModelUnitsEngrave()); +const ON_DimStyle ON_DimStyle::DefaultFeetEngrave(Internal_DimStyleFeetEngrave()); +const ON_DimStyle ON_DimStyle::DefaultMillimeterEngrave(Internal_DimStyleMillimeterEngrave()); +const ON_DimStyle ON_DimStyle::DefaultModelUnitsEngrave(Internal_DimStyleModelUnitsEngrave()); const ON_StackedText ON_StackedText::Empty; const ON_TextRun ON_TextRun::Empty; @@ -2733,7 +2755,7 @@ const ON_SubDComponentTest ON_SubDComponentTest::AllFail((ON__UINT_PTR)0); const ON_SubDEdgeChain ON_SubDEdgeChain::Empty; -static ON_SubDSectorSurfacePoint ON_SubDSectorLimitPoint_Init(double x) +static ON_SubDSectorSurfacePoint Internal_ON_SubDSectorLimitPoint_Init(double x) { ON_SubDSectorSurfacePoint lp; memset(&lp, 0, sizeof(lp)); @@ -2757,9 +2779,9 @@ static ON_SubDSectorSurfacePoint ON_SubDSectorLimitPoint_Init(double x) return lp; } -const ON_SubDSectorSurfacePoint ON_SubDSectorSurfacePoint::Unset = ON_SubDSectorLimitPoint_Init(ON_UNSET_VALUE); -const ON_SubDSectorSurfacePoint ON_SubDSectorSurfacePoint::Nan = ON_SubDSectorLimitPoint_Init(ON_DBL_QNAN); -const ON_SubDSectorSurfacePoint ON_SubDSectorSurfacePoint::Zero = ON_SubDSectorLimitPoint_Init(0.0); +const ON_SubDSectorSurfacePoint ON_SubDSectorSurfacePoint::Unset = Internal_ON_SubDSectorLimitPoint_Init(ON_UNSET_VALUE); +const ON_SubDSectorSurfacePoint ON_SubDSectorSurfacePoint::Nan = Internal_ON_SubDSectorLimitPoint_Init(ON_DBL_QNAN); +const ON_SubDSectorSurfacePoint ON_SubDSectorSurfacePoint::Zero = Internal_ON_SubDSectorLimitPoint_Init(0.0); const ON_SubDVertexSurfacePointCoefficient ON_SubDVertexSurfacePointCoefficient::Zero = ON_SubDVertexSurfacePointCoefficient::Create(nullptr,nullptr,0.0); const ON_SubDVertexSurfacePointCoefficient ON_SubDVertexSurfacePointCoefficient::Nan = ON_SubDVertexSurfacePointCoefficient::Create(nullptr,nullptr,ON_DBL_QNAN); @@ -2800,7 +2822,7 @@ const ON_ComponentStatus ON_ComponentStatus::Locked = ON_ComponentStatus(ON_Comp const ON_ComponentStatus ON_ComponentStatus::Deleted = ON_ComponentStatus(ON_ComponentState::Deleted); const ON_ComponentStatus ON_ComponentStatus::Damaged = ON_ComponentStatus(ON_ComponentState::Damaged); const ON_ComponentStatus ON_ComponentStatus::Marked = ON_ComponentStatus(ON_ComponentState::RuntimeMarkSet); -static ON_ComponentStatus ON_ComponentStatus_AllSet() +static ON_ComponentStatus Internal_ON_ComponentStatus_AllSet() { ON_ComponentStatus s; s.SetStates(ON_ComponentStatus::SelectedPersistent); @@ -2810,7 +2832,7 @@ static ON_ComponentStatus ON_ComponentStatus_AllSet() s.SetStates(ON_ComponentStatus::Damaged); return s; } -const ON_ComponentStatus ON_ComponentStatus::AllSet = ON_ComponentStatus_AllSet(); +const ON_ComponentStatus ON_ComponentStatus::AllSet = Internal_ON_ComponentStatus_AllSet(); static ON_AggregateComponentStatus ON_Internal_AggregateComponentStatus_Init(int k) { @@ -2837,28 +2859,28 @@ const ON_AggregateComponentStatusEx ON_AggregateComponentStatusEx::NotCurrent = const ON_SubDComponentPoint ON_SubDComponentPoint::Unset = ON_SubDComponentPoint(); -static ON_SubDMeshFragmentGrid EmptyLimitMeshFragmentGridInit() +static ON_SubDMeshFragmentGrid Internal_EmptyLimitMeshFragmentGridInit() { ON_SubDMeshFragmentGrid empty; memset(&empty, 0, sizeof(empty)); return empty; } -static ON_SubDMeshFragment EmptyLimitMeshFragmentInit() +static ON_SubDMeshFragment Internal_EmptyLimitMeshFragmentInit() { ON_SubDMeshFragment empty; memset(&empty, 0, sizeof(empty)); return empty; } -const ON_SubDMeshFragmentGrid ON_SubDMeshFragmentGrid::Empty = EmptyLimitMeshFragmentGridInit(); -const ON_SubDMeshFragment ON_SubDMeshFragment::Empty = EmptyLimitMeshFragmentInit(); +const ON_SubDMeshFragmentGrid ON_SubDMeshFragmentGrid::Empty = Internal_EmptyLimitMeshFragmentGridInit(); +const ON_SubDMeshFragment ON_SubDMeshFragment::Empty = Internal_EmptyLimitMeshFragmentInit(); const ON_SubDMeshFragmentGrid ON_SubDMeshFragmentGrid::OneQuadGrid = ON_SubDMeshFragmentGrid::QuadGridFromSideSegmentCount(1, 0); -static ON_SubDComponentBase UnsetComponentBaseInit() +static const ON_SubDComponentBase Internal_UnsetComponentBaseInit() { // For efficiency, ON_SubDComponentBase() does not waste time // m_cache_subd_P[], m_displacementV[] @@ -2868,7 +2890,7 @@ static ON_SubDComponentBase UnsetComponentBaseInit() return unset; } -static ON_SubDVertex EmptyVertexInit() +static const ON_SubDVertex Internal_EmptyVertexInit() { // For efficiency, ON_SubDVertex() does not waste time // initializing m_limitP[], ..., m_cache_subd_P[], m_displacementV[] @@ -2878,7 +2900,7 @@ static ON_SubDVertex EmptyVertexInit() return empty; } -static ON_SubDEdge EmptyEdgeInit() +static const ON_SubDEdge Internal_EmptyEdgeInit() { // For efficiency, ON_SubDEdge() does not waste time // initializing m_cache_subd_P[], m_displacementV[] @@ -2888,7 +2910,7 @@ static ON_SubDEdge EmptyEdgeInit() return empty; } -static ON_SubDFace EmptyFaceInit() +static const ON_SubDFace Internal_EmptyFaceInit() { // For efficiency, ON_SubDFace() does not waste time // initializing m_cache_subd_P[], m_displacementV[] @@ -2898,10 +2920,10 @@ static ON_SubDFace EmptyFaceInit() return empty; } -const ON_SubDComponentBase ON_SubDComponentBase::Unset = UnsetComponentBaseInit(); -const ON_SubDVertex ON_SubDVertex::Empty = EmptyVertexInit(); -const ON_SubDEdge ON_SubDEdge::Empty = EmptyEdgeInit(); -const ON_SubDFace ON_SubDFace::Empty = EmptyFaceInit(); +const ON_SubDComponentBase ON_SubDComponentBase::Unset = Internal_UnsetComponentBaseInit(); +const ON_SubDVertex ON_SubDVertex::Empty = Internal_EmptyVertexInit(); +const ON_SubDEdge ON_SubDEdge::Empty = Internal_EmptyEdgeInit(); +const ON_SubDFace ON_SubDFace::Empty = Internal_EmptyFaceInit(); const ON_SubD ON_SubD::Empty; const ON_SubDRef ON_SubDRef::Empty; diff --git a/opennurbs_subd.cpp b/opennurbs_subd.cpp index db81970d..ab3a3eb0 100644 --- a/opennurbs_subd.cpp +++ b/opennurbs_subd.cpp @@ -8650,15 +8650,16 @@ unsigned int ON_SubD::DumpTopology( { const ON_MappingTag mapping_tag = this->TextureMappingTag(true); + const bool bUnsetMappingTag = ON_MappingTag::Unset == mapping_tag; + const bool bSurfaceParameterMappingTag - = (0 == ON_MappingTag::CompareAll(ON_MappingTag::SurfaceParameterMapping, mapping_tag)) - || (bIsTextHash && (ON_TextureMapping::TYPE::srfp_mapping == mapping_tag.m_mapping_type || ON_MappingTag::SurfaceParameterMapping.m_mapping_id == mapping_tag.m_mapping_id)) + = false == bUnsetMappingTag + && ( + ON_MappingTag::SurfaceParameterMapping == mapping_tag + || (bIsTextHash && (ON_TextureMapping::TYPE::srfp_mapping == mapping_tag.m_mapping_type || ON_MappingTag::SurfaceParameterMapping.m_mapping_id == mapping_tag.m_mapping_id)) + ) ; - const bool bUnsetMappingTag - = ((false == bSurfaceParameterMappingTag) && - (0 == ON_MappingTag::CompareAll(ON_MappingTag::Unset, mapping_tag))) || - ((bIsTextHash && (ON_TextureMapping::TYPE::no_mapping == mapping_tag.m_mapping_type || ON_nil_uuid == mapping_tag.m_mapping_id))); // NOTE: the mapping tag is only applied when subd_texture_coordinate_type = FromMapping if (ON_SubDTextureCoordinateType::FromMapping == subd_texture_coordinate_type && false == bUnsetMappingTag) @@ -8742,9 +8743,18 @@ unsigned int ON_SubD::DumpTopology( frament_texture_settings_hash.Dump(text_log); text_log.PrintNewLine(); } + } - if (false == text_log.IsTextHash()) + if (false == text_log.IsTextHash()) + { + text_log.Print(L"Fragment per vertex color settings:\n"); { + ON_TextLogIndent indent1(text_log); + 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); const ON_SHA1_Hash subd_fragment_color_settings_hash = this->FragmentColorsSettingsHash(); text_log.Print(L"FragmentColorsSettingsHash() = "); subd_fragment_color_settings_hash.Dump(text_log); @@ -9084,6 +9094,21 @@ const ON_SHA1_Hash ON_SubDimple::FaceHash(ON_SubDHashType hash_type) const return Internal_FaceHash(hash_type, ActiveLevel().m_face[0], this->ActiveLevelIndex(), fidit); } + +static void Internal_AccumulateFragmentColorArrayHash(ON_SHA1& sha1, const ON_Color* a, unsigned count, size_t stride) +{ + if (nullptr != a && count > 0) + { + sha1.AccumulateInteger32(count); + for (unsigned i = 0; i < count; ++i) + { + const unsigned c = a[0]; + sha1.AccumulateInteger32(c); + a += stride; + } + } +} + static void Internal_AccumulateFragmentArrayHash(ON_SHA1& sha1, size_t dim, const double* a, unsigned count, size_t stride) { if (nullptr != a && count > 0 && dim > 0 && (0 == stride || stride >= dim)) @@ -10443,12 +10468,45 @@ unsigned int ON_SubDLevel::DumpTopology( return topology_error_count; } +static void Internal_DumpFragmentColorArray(ON_TextLog& text_log, const wchar_t* description, const ON_Color* a, unsigned count, size_t stride) +{ + if (nullptr != a && count > 0 && stride >= 1) + { + text_log.Print(L"%ls = ", description); + if (count <= 4) + { + text_log.Print("{"); + for (unsigned i = 0; i < count; ++i) + { + if (0 != i) + text_log.Print(L","); + a->ToText(ON_Color::TextFormat::HashRGBa, 0, true, text_log); + a += stride; + } + text_log.Print("}"); + } + else + { + a->ToText(ON_Color::TextFormat::HashRGBa, 0, true, text_log); + ON_SHA1 sha1; + Internal_AccumulateFragmentColorArrayHash(sha1, a, count, stride); + const ON_wString s = sha1.Hash().ToString(true); + text_log.Print(L" ... SHA1 hash=%ls", static_cast(s)); + } + } + else + { + text_log.Print(L"%ls: Not set.", description); + } + text_log.PrintNewLine(); +} + static void Internal_DumpFragmentArray(ON_TextLog& text_log, const wchar_t* description, size_t dim, const double* a, unsigned count, size_t stride) { if (nullptr != a && count > 0 && dim > 0 && stride >= dim) { text_log.Print(L"%ls = ", description); - if (4 == count) + if (count <= 4) { text_log.Print("{"); for (unsigned i = 0; i < count; ++i) @@ -10538,7 +10596,12 @@ void ON_SubDMeshFragment::Dump(ON_TextLog& text_log) const text_log, L"curvatures", 2, // 2 principal (const double*)(CurvatureArray(cl)), CurvatureArrayCount(cl), - sizeof(ON_SurfaceCurvature)/sizeof(double) + sizeof(ON_SurfaceCurvature)/sizeof(double)); + Internal_DumpFragmentColorArray( + text_log, L"colors", + ColorArray(cl), + ColorArrayCount(cl), + ColorArrayStride(cl) ); } } @@ -13610,8 +13673,8 @@ private: private: // prohibit use - no implementation - ON_ScratchBuffer(const ON_ScratchBuffer&); - ON_ScratchBuffer& operator-(const ON_ScratchBuffer&); + ON_ScratchBuffer(const ON_ScratchBuffer&) = delete; + ON_ScratchBuffer& operator=(const ON_ScratchBuffer&) = delete; }; class FACE_AND_FACE_POINT @@ -17373,11 +17436,20 @@ bool ON_SubDimple::CopyEvaluationCacheForExperts(const ON_SubDimple& src) { const ON_SubDLevel* src_level = src.ActiveLevelConstPointer(); ON_SubDLevel* this_level = this->ActiveLevelPointer(); - return (nullptr != src_level && nullptr != this_level) ? this_level->CopyEvaluationCacheForExperts(this->m_heap , *src_level, src.m_heap) : false; + 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) + { + 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) +bool ON_SubDLevel::CopyEvaluationCacheForExperts( ON_SubDHeap& this_heap, const ON_SubDLevel& src, const ON_SubDHeap& src_heap, bool& bFragmentsWereCopied) { + bFragmentsWereCopied = false; // Validate conditions for coping the cached evaluation information if ( this == &src @@ -17640,7 +17712,10 @@ bool ON_SubDLevel::CopyEvaluationCacheForExperts( ON_SubDHeap& this_heap, const if ( false == this_face->SavedSubdivisionPointIsSet()) this_face->SetSavedSubdivisionPoint(subdivision_point); if (nullptr == this_face->MeshFragments() && nullptr != src_face->MeshFragments()) - this_heap.CopyMeshFragments(src_face, subd_display_density, this_face); + { + 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 6fe6f7a7..880a07a2 100644 --- a/opennurbs_subd.h +++ b/opennurbs_subd.h @@ -8237,13 +8237,57 @@ public: ) ) const; + + /// + /// Determing if this SubD's mesh fragments have per vertex color settings. + /// + /// + /// If this SubD has mesh fragments with per vertex colors, then true is returned. + /// Otherwise false is returned. + /// + bool HasFragmentColors() const; + + /// + /// + /// 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_tag + ) const; + + /// + /// + /// If this SubD has mesh fragments with per vertex colors and + /// color_settings_hash = FragmentColorsSettingsHash(), then true is returned. + /// Otherwise false is returned. + /// + bool HasFragmentColors( + ON_SHA1_Hash color_settings_hash + ) const; + + /// + /// + /// + /// If this SubD has mesh fragments with per vertex colors and + /// color_settings_hash = FragmentColorsSettingsHash() and + /// color_tag = FragmentColorsMappingTag(), then true is returned. + /// Otherwise false is returned. + /// + bool HasFragmentColors( + ON_SHA1_Hash color_settings_hash, + ON_MappingTag color_tag + ) const; + + /* Description: Clear all fragment vertex colors Parameters: bClearFragmentColorsMappingTag - [in] When in doubt, pass true. - If true, the mapping tag associated with the fragment vertex colors is unset as well. + If true, the mapping tag and hash associated with the fragment vertex colors are unset as well. */ void ClearFragmentColors( bool bClearFragmentColorsMappingTag @@ -8274,6 +8318,8 @@ public: */ void SetFragmentColorsMappingTag(const class ON_MappingTag&) const; + + public: /* Description: @@ -11430,37 +11476,63 @@ public: /* Returns: - If the grid has memory to store curvatures, then VertexCount() is returned. + If the grid has memory to store curvatures, then VertexCapacity() is returned. Otherwise 0 is returned. Remarks: - Use CurvaturesExist() or CurvatureCount() to determine if the curvature values are actually set. + Use CurvatureCount() > 0 to determine if the curvature values are actually set. */ unsigned int CurvatureCapacity() const; + /// + /// Specifies which array (surface points or control net corners) + /// + /// If curvature are set, a pointer to the curvatures in the specified array. + /// Otherwise, nullptr is returned. + /// const ON_SurfaceCurvature* CurvatureArray(ON_SubDComponentLocation subd_appearance)const; + + /// + /// Specifies which array (surface points or control net corners) + /// + /// If curvature are set, the number of curvatures in the specified array. + /// Otherwise, 0 is returned. + /// unsigned CurvatureArrayCount(ON_SubDComponentLocation subd_appearance) const; + + size_t CurvatureArrayStride(ON_SubDComponentLocation subd_appearance) const; + + /* + Description: + Get the principal surface curvature for the specified fragment grid point. + Parameters: + grid2dex_i - [in] + 0 <= grid2dex_i < m_grid.SidePointCount() + grid2dex_j - [in] + 0 <= grid2dex_j < m_grid.SidePointCount() + Returns: + The principal surface curvature for the specified fragment grid point. + When curvatures are not set, ON_SurfaceCurvature::Nan is returned. + */ + const ON_SurfaceCurvature VertexCurvature( + unsigned grid2dex_i, + unsigned grid2dex_j + ) const; + + const ON_SurfaceCurvature VertexCurvature( + ON_2udex grid2dex + ) const; + + const ON_SurfaceCurvature VertexCurvature( + unsigned grid_point_index + ) const; + /* Call ClearCurvatures() if the fragment points are changed and any existing curvature values are now invalid. */ void ClearCurvatures() const; - /* - Description: - Computes curvature values at grid points for this fragment. - Note that fragment curvature values are a mutable property - and can be set at any time after the fragment's points are set. - Parameters: - bLazy - [in] - If bLazy is true and if CurvaturesExist() is true, then no changes are made. - If bLazy is false, the curvature values are unconditionally calculated from the - fragment's surface and saved in m_K[]. - Returns: - True if curvatures are set. - False if curvatures cannot be set. - */ - bool SetCurvatures(bool bLazy) const; /* Returns: @@ -11556,15 +11628,66 @@ public: Otherwise 0 is returned. Remarks: Use ColorCapacity() to get the capacity of m_C[]. + */ /* + Returns: + If the grid has memory to store curvatures, then VertexCapacity() is returned. + Otherwise 0 is returned. + Remarks: + Use CurvaturesExist() or CurvatureCount() to determine if the curvature values are actually set. */ unsigned int ColorCount() const; + /* + Returns: + If the grid has memory to store colors, then VertexCapacity() is returned. + Otherwise 0 is returned. + Remarks: + Use ColorCount() > 0 to determine if the color values are actually set. + */ unsigned int ColorCapacity() const; + /// + /// Specifies which array (surface points or control net corners) + /// + /// If colors are set, the number of curvatures in the specified array. + /// Otherwise, 0 is returned. + /// const ON_Color* ColorArray(ON_SubDComponentLocation subd_appearance)const; size_t ColorArrayStride(ON_SubDComponentLocation subd_appearance)const; + + /// + /// Specifies which array (surface points or control net corners) + /// + /// If colors are set, the number of colors in the specified array. + /// Otherwise, 0 is returned. + /// unsigned ColorArrayCount(ON_SubDComponentLocation subd_appearance) const; + /* + Description: + Get the per vertex color assigned to the specified fragment grid point. + Parameters: + grid2dex_i - [in] + 0 <= grid2dex_i < m_grid.SidePointCount() + grid2dex_j - [in] + 0 <= grid2dex_j < m_grid.SidePointCount() + Returns: + The colo for the specified fragment grid point. + When per vertex colors are not set, ON_Color::Unset is returned. + */ + const ON_Color VertexColor( + unsigned grid2dex_i, + unsigned grid2dex_j + ) const; + + const ON_Color VertexColor( + ON_2udex grid2dex + ) const; + + const ON_Color VertexColor( + unsigned grid_point_index + ) const; + /* Call ClearColors() if vertex colors do not exist or are no longer valid. */ @@ -11620,7 +11743,6 @@ public: ) )const; - public: // Normalized grid parameters useful for appling a texture to the grid are available @@ -17273,10 +17395,11 @@ public: ///The option is not set. Unset = 0, - ///No convex coners. + ///No convex corners. In general,this is the best choice. None = 1, - ///A convex subd corner will appear at input mesh boundary vertices + /// + /// A convex subd corner will appear at input mesh boundary vertices /// where the corner angle <= MaximumConvexCornerAngleRadians() and /// the number of edges the end at the vertex is <= MaximumConvexCornerEdgeCount(). /// @@ -17332,6 +17455,8 @@ public: input mesh boundary vertex becomes a sub-D corner when the number of edges that end at the vertex is <= MaximumConvexCornerEdgeCount() edges and the corner angle is <= MaximumConvexCornerAngleRadians(). + + The default value is 2pi/3 = 120 degrees. Parameters: maximum_convex_corner_angle_radians - [in] > 0.0 and < ON_PI @@ -17346,6 +17471,8 @@ public: input mesh boundary vertex becomes a sub-D corner when the number of edges that end at the vertex is <= MaximumConvexCornerEdgeCount() edges and the corner angle is <= MaximumConvexCornerAngleRadians(). + + The default value is 2pi/3 = 120 degrees. Returns: The maximum corner angle. */ @@ -17377,10 +17504,11 @@ public: ///The option is not set. Unset = 0, - ///No concave coners. In general, this is the best choice. + ///No concave corners. In general, this is the best choice. None = 1, - ///A concave subd corner will appear at input mesh boundary vertices + /// + /// A concave subd corner will appear at input mesh boundary vertices /// where the corner angle >= MinimumConcaveCornerAngleRadians() and /// the number of edges the end at the vertex is >= MinimumConcaveCornerEdgeCount(). /// @@ -17630,8 +17758,11 @@ private: double m_reserved4 = 0.0; - double m_maximum_convex_corner_angle_radians = 120.0 * ON_DEGREES_TO_RADIANS; // 120 degrees - double m_minimum_concave_corner_angle_radians = 240.0 * ON_DEGREES_TO_RADIANS; // 240 degrees + // default = 2pi/3 = 120 degrees + double m_maximum_convex_corner_angle_radians = 120.0 * ON_DEGREES_TO_RADIANS; + + // default 4pi/3 = 240 degrees + double m_minimum_concave_corner_angle_radians = 240.0 * ON_DEGREES_TO_RADIANS; }; ////////////////////////////////////////////////////////////////////////// diff --git a/opennurbs_subd_copy.cpp b/opennurbs_subd_copy.cpp index 1209148b..b64f2943 100644 --- a/opennurbs_subd_copy.cpp +++ b/opennurbs_subd_copy.cpp @@ -867,6 +867,15 @@ ON_SubDimple::ON_SubDimple(const ON_SubDimple& src) m_texture_coordinate_type = src.m_texture_coordinate_type; m_texture_mapping_tag = src.m_texture_mapping_tag; + // NOTE WELL: (Dale Lear Aug 2023) + // 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; + m_face_packing_id = src.m_face_packing_id; m_face_packing_topology_hash = src.m_face_packing_topology_hash; m_face_packing_topology_hash.m_subd_runtime_serial_number diff --git a/opennurbs_subd_data.h b/opennurbs_subd_data.h index 529799aa..daf85149 100644 --- a/opennurbs_subd_data.h +++ b/opennurbs_subd_data.h @@ -1160,7 +1160,12 @@ public: void ClearEvaluationCache() const; - bool CopyEvaluationCacheForExperts(class ON_SubDHeap& this_heap, const ON_SubDLevel& src, const class ON_SubDHeap& src_heap); + bool CopyEvaluationCacheForExperts( + class ON_SubDHeap& this_heap, + const ON_SubDLevel& src, + const class ON_SubDHeap& src_heap, + bool& bFragmentsWereCopied + ); void ClearTopologicalAttributes() const { diff --git a/opennurbs_subd_fragment.cpp b/opennurbs_subd_fragment.cpp index d7c94a9d..ab7590ae 100644 --- a/opennurbs_subd_fragment.cpp +++ b/opennurbs_subd_fragment.cpp @@ -374,6 +374,12 @@ unsigned ON_SubDMeshFragment::CurvatureArrayCount(ON_SubDComponentLocation subd_ return (ON_SubDComponentLocation::ControlNet == subd_appearance) ? 4U : CurvatureCount(); } +size_t ON_SubDMeshFragment::CurvatureArrayStride(ON_SubDComponentLocation subd_appearance) const +{ + return (ON_SubDComponentLocation::ControlNet == subd_appearance) ? 1 : m_K_stride; +} + + const ON_Color* ON_SubDMeshFragment::ColorArray(ON_SubDComponentLocation subd_appearance) const { return (ON_SubDComponentLocation::ControlNet == subd_appearance) ? &m_ctrlnetC[0] : m_C; @@ -396,6 +402,31 @@ bool ON_SubDMeshFragment::ColorsExistForExperts() const return (0 != (m_vertex_capacity_etc & ON_SubDMeshFragment::EtcColorsExistBit)); } +const ON_Color ON_SubDMeshFragment::VertexColor( + unsigned grid2dex_i, + unsigned grid2dex_j +) const +{ + return VertexColor(m_grid.PointIndexFromGrid2dex(grid2dex_i, grid2dex_j)); +} + +const ON_Color ON_SubDMeshFragment::VertexColor( + ON_2udex grid2dex +) const +{ + return VertexColor(m_grid.PointIndexFromGrid2dex(grid2dex.i, grid2dex.j)); +} + +const ON_Color ON_SubDMeshFragment::VertexColor( + unsigned grid_point_index +) const +{ + return + (grid_point_index < this->ColorCount()) + ? m_C[grid_point_index * m_C_stride] + : ON_Color::UnsetColor; +} + void ON_SubDMeshFragment::ClearColors() const { m_vertex_capacity_etc &= ~ON_SubDMeshFragment::EtcColorsExistBit; @@ -418,6 +449,31 @@ bool ON_SubDMeshFragment::CurvaturesExistForExperts() const return (0 != (m_vertex_capacity_etc & ON_SubDMeshFragment::EtcCurvaturesExistBit)); } +const ON_SurfaceCurvature ON_SubDMeshFragment::VertexCurvature( + unsigned grid2dex_i, + unsigned grid2dex_j +) const +{ + return VertexCurvature(m_grid.PointIndexFromGrid2dex(grid2dex_i, grid2dex_j)); +} + +const ON_SurfaceCurvature ON_SubDMeshFragment::VertexCurvature( + ON_2udex grid2dex +) const +{ + return VertexCurvature(m_grid.PointIndexFromGrid2dex(grid2dex.i, grid2dex.j)); +} + +const ON_SurfaceCurvature ON_SubDMeshFragment::VertexCurvature( + unsigned grid_point_index +) const +{ + return + (grid_point_index < this->CurvatureCount()) + ? m_K[grid_point_index * m_K_stride] + : ON_SurfaceCurvature::Nan; +} + void ON_SubDMeshFragment::ClearCurvatures() const { m_vertex_capacity_etc &= ~ON_SubDMeshFragment::EtcCurvaturesExistBit; @@ -495,7 +551,7 @@ bool ON_SubDMeshFragment::SetColorsFromCallback( const unsigned count = PointArrayCount(subd_appearance); if (count <= 0) break; - if (count != ColorArrayCount(subd_appearance)) + if (count != ColorCapacity()) break; const double* P = PointArray(subd_appearance); @@ -503,10 +559,13 @@ bool ON_SubDMeshFragment::SetColorsFromCallback( if (nullptr == P || Pstride < 3) break; - ON_Color* C = const_cast(ColorArray(subd_appearance)); - const size_t Cstride = ColorArrayStride(subd_appearance); + // Note that ColorsExist() is currently false. We are setting colors now. + ON_Color* C = m_C; if (nullptr == C) break; + const size_t Cstride = this->m_C_stride; + if (Cstride <= 0) + break; const double nan3[3] = { ON_DBL_QNAN, ON_DBL_QNAN, ON_DBL_QNAN }; @@ -521,7 +580,7 @@ bool ON_SubDMeshFragment::SetColorsFromCallback( T = nan3; const ON_SurfaceCurvature* K = CurvatureArray(subd_appearance); - const size_t Kstride = (nullptr != K) ? 1 : 0; + const size_t Kstride = this->CurvatureArrayStride(subd_appearance); (nullptr != K) ? 1 : 0; if (nullptr == K) K = &ON_SurfaceCurvature::Nan; @@ -559,6 +618,7 @@ bool ON_SubDMeshFragment::SetColorsFromCallback( return ColorsExistForExperts(); } + bool ON_SubD::SetFragmentColorsFromCallback( bool bLazySet, ON_SHA1_Hash fragment_colors_settings_hash, @@ -575,7 +635,10 @@ bool ON_SubD::SetFragmentColorsFromCallback( const ON_SurfaceCurvature& K) ) const { - if (bLazySet && fragment_colors_settings_hash == FragmentColorsSettingsHash()) + if (bLazySet + && fragment_colors_settings_hash == FragmentColorsSettingsHash() + && fragment_colors_mapping_tag == FragmentColorsMappingTag() + ) return true; bool bFragmentVetexColorsSet = false; @@ -592,7 +655,12 @@ bool ON_SubD::SetFragmentColorsFromCallback( color_callback ); if (b) + { bFragmentVetexColorsSet = true; + frag->SetColorsExistForExperts(true); + } + else + frag->SetColorsExistForExperts(false); } if (bFragmentVetexColorsSet) { @@ -610,13 +678,67 @@ bool ON_SubD::SetFragmentColorsFromCallback( return bFragmentVetexColorsSet; } +bool ON_SubD::HasFragmentColors() const +{ + 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 (frag->ColorCount() > 0) + return true; + } + } + return false; +} + +bool ON_SubD::HasFragmentColors( + ON_MappingTag color_tag +) const +{ + return + this->FragmentColorsMappingTag() == color_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_tag +) const +{ + return + this->FragmentColorsSettingsHash() == color_settings_hash + && this->FragmentColorsMappingTag() == color_tag + && this->HasFragmentColors(); +} + + void ON_SubD::ClearFragmentColors( bool bClearFragmentColorsMappingTag ) { - if (bClearFragmentColorsMappingTag) - SetFragmentColorsMappingTag(ON_MappingTag::Unset); - SetFragmentColorsFromCallback(false, ON_SHA1_Hash::EmptyContentHash, ON_MappingTag::Unset, 0, nullptr ); + 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()) + frag->SetColorsExistForExperts(false); + if (bClearFragmentColorsMappingTag) + { + subdimple->Internal_SetFragmentColorsSettingsHash(ON_SHA1_Hash::EmptyContentHash); + this->SetFragmentColorsMappingTag(ON_MappingTag::Unset); + } + } } const ON_SHA1_Hash ON_SubD::FragmentColorsSettingsHash() const @@ -1664,12 +1786,19 @@ const ON_Color ON_SubDMeshFragment::CornerColor( const ON_SurfaceCurvature ON_SubDMeshFragment::CornerCurvature(unsigned int grid_corner_index) const { - if (grid_corner_index >= 4 || nullptr == m_K || nullptr == m_grid.m_S) - return ON_SurfaceCurvature::Nan; + for (;;) + { + if (grid_corner_index >= 4 || nullptr == m_grid.m_S) + break; - const unsigned int i = m_grid.m_S[grid_corner_index * m_grid.m_side_segment_count]; + const unsigned n = this->CurvatureCount(); + const unsigned int i = m_grid.m_S[grid_corner_index * m_grid.m_side_segment_count]; + if (i >= n) + break; - return m_K[i]; + return m_K[i]; + } + return ON_SurfaceCurvature::Nan; } const ON_3dPoint ON_SubDMeshFragment::TextureCoordinateCorner( @@ -2554,7 +2683,7 @@ bool ON_SubDMeshFragment::CopyFrom( ON_SurfaceCurvature* src_k1 = src_k + src_k_stride * src_V_count; while (src_k < src_k1) { - k = src_k; + *k = *src_k; k += k_stride; src_k += src_k_stride; } @@ -2580,7 +2709,7 @@ bool ON_SubDMeshFragment::CopyFrom( ON_Color* src_c1 = src_c + src_c_stride * src_V_count; while (src_c < src_c1) { - c = src_c; + *c = *src_c; c += c_stride; src_c += src_c_stride; } diff --git a/opennurbs_subd_matrix.cpp b/opennurbs_subd_matrix.cpp index 7c4c9791..c8fa9dc8 100644 --- a/opennurbs_subd_matrix.cpp +++ b/opennurbs_subd_matrix.cpp @@ -2992,8 +2992,6 @@ double ON_SubDMatrix::TestEvaluation( double max_d = 0.0; const unsigned int maximum_fail_count = 10; - const char* sSubDTypeName = "ccquad"; - for (size_t vertex_tag_index = vertex_tag_index0; vertex_tag_index < vertex_tag_count; vertex_tag_index++) { const ON_SubDVertexTag vertex_tag_for_scope = vertex_tags[vertex_tag_index]; @@ -3024,7 +3022,8 @@ double ON_SubDMatrix::TestEvaluation( if (false == test_sector_type.SurfaceEvaluationCoefficientsAvailable()) continue; const unsigned int N = test_sector_type.EdgeCount(); - double d = ON_SubDMatrix::FromCache(test_sector_type).TestEvaluation(); + const ON_SubDMatrix& SM = ON_SubDMatrix::FromCache(test_sector_type); + double d = SM.TestEvaluation(); if (d >= 0.0) { pass_count++; @@ -3039,14 +3038,97 @@ double ON_SubDMatrix::TestEvaluation( { ON_String test_description; if (ON_SubDVertexTag::Corner == vertex_tag_for_scope) - test_description.Format("%s, %s, %u faces, %u edges, angle = %u/%u 2pi", sSubDTypeName, sVertexTagName, F, N, corner_sector_angle_index, ON_SubDSectorType::MaximumCornerAngleIndex); + test_description.Format("%s, %u faces, %u edges, angle = %u/%u 2pi", sVertexTagName, F, N, corner_sector_angle_index, ON_SubDSectorType::MaximumCornerAngleIndex); else - test_description.Format("%s, %s, %u faces, %u edges", sSubDTypeName, sVertexTagName, F, N); + test_description.Format("%s, %u faces, %u edges", sVertexTagName, F, N); if (d >= 0.0) text_log->Print("Test( %s) passed. Deviation = %g\n", (const char*)test_description, d); else text_log->Print("Test( %s ) failed\n", (const char*)test_description); + + if (SM.m_R > 0) + { + // Print evauation coefficients. + const ON_TextLogIndent indent1(*text_log); + text_log->Print("Limit suface evaluation coefficients:\n"); + const ON_TextLogIndent indent2(*text_log); + for (unsigned Ldex = 0; Ldex < 3; ++Ldex) + { + const double* L; + ON_String Lid; + switch (Ldex) + { + case 0u: + L = SM.m_LP; + Lid = "point"; + break; + case 1u: + L = SM.m_L1; + Lid = "tangent[1]"; + break; + case 2u: + L = SM.m_L2; + Lid = "tangent[2]"; + break; + default: + L = nullptr; + break; + } + if (nullptr == L) + continue; + char sep[] = { ' ', '=', ' ', 0 }; + unsigned termcount = 0; + if ( 0.0 == L[0]) + text_log->Print("%s", static_cast(Lid)); + else + { + if (1.0 == L[0]) + text_log->Print("%s%sV", static_cast(Lid), sep, L[0]); + else if (-1.0 == L[0]) + text_log->Print("%s%s-V", static_cast(Lid), sep, L[0]); + else + text_log->Print("%s%s%g*V", static_cast(Lid), sep, L[0]); + ++termcount; + } + bool bPopIndent = false; + for (unsigned r = 1u; r < SM.m_R; ++r) + { + double c = fabs(L[r]); + if (0.0 == L[r]) + continue; + ++termcount; + if (termcount >= 2) + { + c = fabs(c); + sep[1] = (L[r] < 0.0) ? '-' : '+'; + } + + if (8 == termcount && SM.m_R > 9 && false == bPopIndent) + { + text_log->PrintNewLine(); + text_log->PushIndent(); + bPopIndent = true; + } + if (1.0 == c) + text_log->Print("%s", sep); + else + text_log->Print("%s%g*", sep, c); + if (1u == r % 2u) + text_log->Print("E%u", (r+1u)/2u); + else + text_log->Print("Q%u", r/2u); + if (14 == termcount && r < SM.m_R - 2) + { + text_log->Print(" + ..."); + r = SM.m_R - 2; + } + } + text_log->PrintNewLine(); + if (bPopIndent) + text_log->PopIndent(); + } + } } if (ON_SubDVertexTag::Corner != vertex_tag_for_scope) break; diff --git a/opennurbs_sun.cpp b/opennurbs_sun.cpp index 5527b076..2933d2b4 100644 --- a/opennurbs_sun.cpp +++ b/opennurbs_sun.cpp @@ -22,6 +22,9 @@ #error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs #endif +// ShadowIntensity in the Sun and Skylight are currently unused. The only ShadowIntensity that's actually +// used is the one in the lights. See [SHADOW_INTENSITY_UNUSED] + static const wchar_t* XMLPath_Sun(void) { return ON_RDK_DOCUMENT ON_XML_SLASH ON_RDK_SETTINGS ON_XML_SLASH ON_RDK_SUN; @@ -826,11 +829,13 @@ void ON_Sun::CImpl::SetIntensity(double d) double ON_Sun::CImpl::ShadowIntensity(void) const { + // ShadowIntensity is currently unused. See [SHADOW_INTENSITY_UNUSED] return GetParameter(XMLPath_Sun(), ON_RDK_SUN_SHADOW_INTENSITY, 1.0); } void ON_Sun::CImpl::SetShadowIntensity(double d) { + // ShadowIntensity is currently unused. See [SHADOW_INTENSITY_UNUSED] SetParameter(XMLPath_Sun(), ON_RDK_SUN_SHADOW_INTENSITY, std::max(0.0, std::min(1.0, d))); } @@ -1148,6 +1153,7 @@ double ON_Sun::Intensity(void) const double ON_Sun::ShadowIntensity(void) const { + // ShadowIntensity is currently unused. See [SHADOW_INTENSITY_UNUSED] return _impl->ShadowIntensity(); } @@ -1239,6 +1245,7 @@ void ON_Sun::SetIntensity(double d) void ON_Sun::SetShadowIntensity(double d) { + // ShadowIntensity is currently unused. See [SHADOW_INTENSITY_UNUSED] _impl->SetShadowIntensity(d); } diff --git a/opennurbs_sun.h b/opennurbs_sun.h index 38f45b73..2e748315 100644 --- a/opennurbs_sun.h +++ b/opennurbs_sun.h @@ -179,7 +179,7 @@ public: // Returns the intensity to be used for the sun. This is 1.0 by default. virtual double Intensity(void) const; - // Returns the shadow intensity to be used for the sun. This is 1.0 by default. 0.0 turns off all shadows. + // This is currently unused. virtual double ShadowIntensity(void) const; // Set whether or not enabling/disabling the sun is allowed. @@ -233,7 +233,7 @@ public: // Returns true if successful, false if the date is out of range. virtual bool SetLocalDateTime(int year, int month, int day, double hours); - // Set the shadow intensity to be used for the sun. This is 1.0 by default. 0.0 turns off all shadows. + // This is currently unused. virtual void SetShadowIntensity(double intensity); // Set the intensity to be used for the sun. This is 1.0 by default. diff --git a/opennurbs_symmetry.cpp b/opennurbs_symmetry.cpp index 6bdf2185..ae1a8e38 100644 --- a/opennurbs_symmetry.cpp +++ b/opennurbs_symmetry.cpp @@ -1052,23 +1052,28 @@ bool ON_Symmetry::Read(ON_BinaryArchive& archive) void ON_PlaneEquation::Dump(class ON_TextLog& text_log) const { // print -0 as 0. - double c[4] = { (0.0==x) ? 0.0 : x,(0.0 == y) ? 0.0 : y,(0.0 == z) ? 0.0 : z,(0.0 == d) ? 0.0 : d }; - for (int i = 0; i < 3; ++i) + const double c[4] = { (0.0 == x) ? 0.0 : x,(0.0 == y) ? 0.0 : y,(0.0 == z) ? 0.0 : z,(0.0 == d) ? 0.0 : d }; + if ( ON_IS_VALID(c[0]) && ON_IS_VALID(c[1]) && ON_IS_VALID(c[2]) && ON_IS_VALID(c[3]) ) { - if (false == (0.0 != c[i] && 0.0 == c[(i + 1) % 3] && 0.0 == c[(i + 2) % 3]) ) - continue; - const char* coord = (0 == i) ? "x" : ((1 == i) ? "y" : "z"); - if (0.0 == c[3]) - text_log.Print(L"%s = 0", coord); - else if (1.0 == c[i]) - text_log.Print(L"%s = %g", coord, -c[3]); - else - text_log.Print(L"%g*%s = %g", c[i] , coord, -c[3]); - return; + for (int i = 0; i < 3; ++i) + { + if (false == (0.0 != c[i] && 0.0 == c[(i + 1) % 3] && 0.0 == c[(i + 2) % 3])) + continue; + const char* coord = (0 == i) ? "x" : ((1 == i) ? "y" : "z"); + if (0.0 == c[3]) + text_log.Print("%s = 0", coord); + else if (1.0 == c[i]) + text_log.Print("%s = %g", coord, -c[3]); + else if (-1.0 == c[i]) + text_log.Print("-%s = %g", coord, -c[3]); + else + text_log.Print("%g*%s = %g", c[i], coord, -c[3]); + return; + } } // general case - text_log.Print(L"%g*x + %g*y + %g*z + %g = 0", c[0], c[1], c[2], c[3]); + text_log.Print("%g*x + %g*y + %g*z + %g = 0", c[0], c[1], c[2], c[3]); } void ON_Symmetry::Dump(ON_TextLog& text_log) const diff --git a/opennurbs_textlog.cpp b/opennurbs_textlog.cpp index 797f78f9..6a2acb52 100644 --- a/opennurbs_textlog.cpp +++ b/opennurbs_textlog.cpp @@ -54,6 +54,22 @@ ON_TextLogLevelOfDetail::ON_TextLogLevelOfDetail( m_text_log.SetLevelOfDetail(level_of_detail); } +ON_TextLogLevelOfDetail::ON_TextLogLevelOfDetail( + class ON_TextLog& text_log, + int delta_lod +) + : m_text_log(text_log) + , m_saved_level_of_detail(text_log.GetLevelOfDetail()) +{ + const int new_lod = ((int)static_cast(m_saved_level_of_detail)) + delta_lod; + if (new_lod <= 0) + m_text_log.SetLevelOfDetail(ON_TextLog::LevelOfDetail::Minimum); + else if (((unsigned)new_lod) >= static_cast(ON_TextLog::LevelOfDetail::Maximum)) + m_text_log.SetLevelOfDetail(ON_TextLog::LevelOfDetail::Maximum); + else + m_text_log.SetLevelOfDetail(ON_TextLog::LevelOfDetailFromUnsigned((unsigned)new_lod)); +} + ON_TextLogLevelOfDetail::~ON_TextLogLevelOfDetail() { m_text_log.SetLevelOfDetail(m_saved_level_of_detail); @@ -130,6 +146,22 @@ ON_TextLog::LevelOfDetail ON_TextLog::GetLevelOfDetail() const return m_level_of_detail; } +ON_TextLog::LevelOfDetail ON_TextLog::IncreaseLevelOfDetail() +{ + ON_TextLog::LevelOfDetail prev_lod = m_level_of_detail; + if (prev_lod < ON_TextLog::LevelOfDetail::Maximum) + SetLevelOfDetail(ON_TextLog::LevelOfDetailFromUnsigned(static_cast(prev_lod) + 1u)); + return prev_lod; +} + +ON_TextLog::LevelOfDetail ON_TextLog::DecreaseLevelOfDetail() +{ + ON_TextLog::LevelOfDetail prev_lod = m_level_of_detail; + if (prev_lod > ON_TextLog::LevelOfDetail::Minimum) + SetLevelOfDetail(ON_TextLog::LevelOfDetailFromUnsigned(static_cast(prev_lod) - 1u)); + return prev_lod; +} + bool ON_TextLog::LevelOfDetailIsAtLeast(ON_TextLog::LevelOfDetail level_of_detail) { return static_cast(m_level_of_detail) >= static_cast(level_of_detail); @@ -440,14 +472,22 @@ void ON_TextLog::Print( const ON_3dVector& p ) void ON_TextLog::Print( const ON_Xform& xform ) { - if ( xform.IsIdentity() ) + if (ON_Xform::IdentityTransformation == xform) { Print("ON_Xform::IdentityTransformation\n"); } - else if ( xform.IsZero() ) + else if (ON_Xform::ZeroTransformation == xform) { Print("ON_Xform::ZeroTransformation\n"); } + else if (ON_Xform::Zero4x4 == xform) + { + Print("ON_Xform::Zero4x4\n"); + } + else if (ON_Xform::Unset == xform) + { + Print("ON_Xform::Unset\n"); + } else { Print(static_cast< const char* >(m_double4_format),xform[0][0],xform[0][1],xform[0][2],xform[0][3]); diff --git a/opennurbs_textlog.h b/opennurbs_textlog.h index 3b2120c3..1ded1f64 100644 --- a/opennurbs_textlog.h +++ b/opennurbs_textlog.h @@ -93,6 +93,23 @@ public: */ ON_TextLog::LevelOfDetail GetLevelOfDetail() const; + /// + /// Increase the level of detail. + /// + /// + /// Level of detail to restore when this scope of increased detail is finished. + /// + ON_TextLog::LevelOfDetail IncreaseLevelOfDetail(); + + /// + /// Decrease the level of detail. + /// + /// + /// Level of detail to restore when this scope of decreased detail is finished. + /// + ON_TextLog::LevelOfDetail DecreaseLevelOfDetail(); + + /* Parameter: level_of_detail - [in] @@ -423,8 +440,8 @@ private: // prevent use of copy construction and operator= // (no implementations) - ON_TextLogIndent(const ON_TextLogIndent&); - ON_TextLogIndent& operator=(const ON_TextLogIndent&); + ON_TextLogIndent(const ON_TextLogIndent&) = delete; + ON_TextLogIndent& operator=(const ON_TextLogIndent&) = delete; }; @@ -442,6 +459,20 @@ public: ON_TextLog::LevelOfDetail level_of_detail ); + /// + /// + /// + /// + /// + /// Amount to change the level of detail. + /// +1 increases the level of detail by a single level. + /// -1 decreases the level of detail by a single level. + /// + ON_TextLogLevelOfDetail( + class ON_TextLog& text_log, + int delta_lod + ); + // The destructor restores the level ot detail the saved value. ~ON_TextLogLevelOfDetail(); diff --git a/opennurbs_texture_mapping.h b/opennurbs_texture_mapping.h index 35f30ca0..e2418f78 100644 --- a/opennurbs_texture_mapping.h +++ b/opennurbs_texture_mapping.h @@ -37,10 +37,19 @@ class ON_CLASS ON_TextureMapping : public ON_ModelComponent public: - static const ON_TextureMapping Unset; // nil id + /// + /// m_type = ON_TextureMapping::TYPE::no_mapping + /// m_id = nil id + /// + static const ON_TextureMapping Unset; - // ON_TextureMapping::SurfaceParameterTextureMapping - // has m_type = ON_TextureMapping::srfp_mapping and m_id = nil; + // {B988A6C2-61A6-45a7-AAEE-9AED7EF4E316} + static const ON_UUID SurfaceParameterTextureMappingId; + + /// + /// m_type = ON_TextureMapping::srfp_mapping + /// m_id = ON_TextureMapping::SurfaceParameterTextureMappingId + /// static const ON_TextureMapping SurfaceParameterTextureMapping; /*