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;
/*