diff --git a/opennurbs_bezier.cpp b/opennurbs_bezier.cpp index 201c68eb..bc44db7b 100644 --- a/opennurbs_bezier.cpp +++ b/opennurbs_bezier.cpp @@ -1176,6 +1176,12 @@ bool ON_Mesh::GetTightBoundingBox( // Now just add verticies of the clipped mesh int vcnt = VertexCount(); + + // 16 Sept 2021, Mikko, RH-49510: + // Bail out if the mesh is bogus. In the associated youtrack item + // this fixes the bounding box of a block being way too big. + if (vcnt < 3) + return false; // n = number of clipping planes. At most 32 clipping planes are allowed so that this function can use unsigned int // to represent the 32 clip predicates. diff --git a/opennurbs_brep.cpp b/opennurbs_brep.cpp index 87810754..b116760e 100644 --- a/opennurbs_brep.cpp +++ b/opennurbs_brep.cpp @@ -8987,6 +8987,7 @@ void ON_Brep::DeleteFace(ON_BrepFace& face, bool bDeleteFaceEdges ) DeleteLoop(loop,bDeleteFaceEdges); } } + DestroyRegionTopology(); } face.m_si = -1; @@ -9564,6 +9565,8 @@ bool ON_Brep::CullUnusedFaces() } } m_F.Shrink(); + if (m_F.Count() < fcount) + DestroyRegionTopology(); return rc; } diff --git a/opennurbs_circle.cpp b/opennurbs_circle.cpp index b245d2e4..6832e460 100644 --- a/opennurbs_circle.cpp +++ b/opennurbs_circle.cpp @@ -550,6 +550,11 @@ bool ON_Circle::Reverse() return true; } +double ON_Circle::MaximumCoordinate() const +{ + return plane.origin.MaximumCoordinate() + radius; +} + int ON_Circle::GetNurbForm( ON_NurbsCurve& nurbscurve ) const { int rc = 0; diff --git a/opennurbs_circle.h b/opennurbs_circle.h index 81396f95..d131e7de 100644 --- a/opennurbs_circle.h +++ b/opennurbs_circle.h @@ -237,6 +237,9 @@ public: bool Reverse(); + // // absolute value of maximum coordinate + double MaximumCoordinate() const; + // Description: // Get a four span rational degree 2 NURBS circle representation // of the circle. diff --git a/opennurbs_dimension.cpp b/opennurbs_dimension.cpp index 47252177..206fc051 100644 --- a/opennurbs_dimension.cpp +++ b/opennurbs_dimension.cpp @@ -523,8 +523,9 @@ bool ON_Dimension::Internal_ReadDimension( break; if (!archive.ReadDouble(&m_distance_scale)) break; - if (ON_nil_uuid == m_detail_measured) - m_distance_scale = 1.0; + // 24-Sep-2021 Dale Fugier, https://mcneel.myjetbrains.com/youtrack/issue/RH-65605 + //if (ON_nil_uuid == m_detail_measured) + // m_distance_scale = 1.0; if (content_version <= 0) { diff --git a/opennurbs_extensions.h b/opennurbs_extensions.h index bf236e59..5543974e 100644 --- a/opennurbs_extensions.h +++ b/opennurbs_extensions.h @@ -2065,18 +2065,18 @@ public: std::shared_ptr ReadWriteReadModel() const; -private: - ONX_ModelTest::Type m_test_type = ONX_ModelTest::Type::Unset; + private: + ONX_ModelTest::Type m_test_type = ONX_ModelTest::Type::Unset; - ON_wString m_source_3dm_file_path; + ON_wString m_source_3dm_file_path; - // if set, used when printing the name of m_source_3dm_file_path in the text - // log so results from different computers can be compared. - ON_wString m_text_log_3dm_file_path; + // if set, used when printing the name of m_source_3dm_file_path in the text + // log so results from different computers can be compared. + ON_wString m_text_log_3dm_file_path; - unsigned int m_model_3dm_file_version[3] = {0}; + unsigned int m_model_3dm_file_version[3]; - unsigned int m_current_test_index = 0; + unsigned int m_current_test_index = 0; ONX_ModelTest::Result m_test_result = ONX_ModelTest::Result::Unset; ONX_ModelTest::Result m_test_results[7] = {}; diff --git a/opennurbs_font.cpp b/opennurbs_font.cpp index 23bff1d2..2b34e325 100644 --- a/opennurbs_font.cpp +++ b/opennurbs_font.cpp @@ -1,3 +1,4 @@ + // // Copyright (c) 1993-2015 Robert McNeel & Associates. All rights reserved. // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert @@ -4337,6 +4338,42 @@ const ON_Font* ON_FontList::FromNames( ); } +const ON_Font* ON_FontList::FromNames2( + const wchar_t* postscript_name, + const wchar_t* windows_logfont_name, + const wchar_t* en_windows_logfont_name, + const wchar_t* family_name, + const wchar_t* en_family_name, + const wchar_t* prefered_face_name, + const wchar_t* en_prefered_face_name, + ON_Font::Weight prefered_weight, + ON_Font::Stretch prefered_stretch, + ON_Font::Style prefered_style, + bool bRequireFaceMatch, + bool bRequireStyleMatch +) const +{ + const bool bMatchUnderlineStrikethroughAndPointSize = false; + return Internal_FromNames2( + postscript_name, + windows_logfont_name, + en_windows_logfont_name, + family_name, + en_family_name, + prefered_face_name, + en_prefered_face_name, + prefered_weight, + prefered_stretch, + prefered_style, + bRequireFaceMatch, + bRequireStyleMatch, + bMatchUnderlineStrikethroughAndPointSize, + false, + false, + 0.0 + ); +} + const ON_Font* ON_FontList::FromNames( const wchar_t* postscript_name, const wchar_t* windows_logfont_name, @@ -4386,6 +4423,45 @@ const ON_Font* ON_FontList::Internal_FromNames( bool bStrikethrough, double point_size ) const +{ + return Internal_FromNames2( + postscript_name, + windows_logfont_name, + windows_logfont_name, + family_name, + family_name, + prefered_face_name, + prefered_face_name, + prefered_weight, + prefered_stretch, + prefered_style, + bRequireFaceMatch, + bRequireStyleMatch, + bMatchUnderlineStrikethroughAndPointSize, + bUnderlined, + bStrikethrough, + point_size + ); +} + +const ON_Font* ON_FontList::Internal_FromNames2( + const wchar_t* postscript_name, + const wchar_t* windows_logfont_name, + const wchar_t* en_windows_logfont_name, + const wchar_t* family_name, + const wchar_t* en_family_name, + const wchar_t* prefered_face_name, + const wchar_t* en_prefered_face_name, + ON_Font::Weight prefered_weight, + ON_Font::Stretch prefered_stretch, + ON_Font::Style prefered_style, + bool bRequireFaceMatch, + bool bRequireStyleMatch, + bool bMatchUnderlineStrikethroughAndPointSize, + bool bUnderlined, + bool bStrikethrough, + double point_size +) const { if (ON_Font::Stretch::Unset == prefered_stretch) bRequireStyleMatch = false; @@ -4414,15 +4490,18 @@ const ON_Font* ON_FontList::Internal_FromNames( key.m_loc_windows_logfont_name = windows_logfont_name; key.m_loc_windows_logfont_name.TrimLeftAndRight(); - key.m_en_windows_logfont_name = key.m_loc_windows_logfont_name; + key.m_en_windows_logfont_name = en_windows_logfont_name; + key.m_en_windows_logfont_name.TrimLeftAndRight(); key.m_loc_family_name = family_name; key.m_loc_family_name.TrimLeftAndRight(); - key.m_en_family_name = key.m_loc_family_name; + key.m_en_family_name = en_family_name; + key.m_en_family_name.TrimLeftAndRight(); key.m_loc_face_name = prefered_face_name; key.m_loc_face_name.TrimLeftAndRight(); - key.m_en_face_name = key.m_loc_face_name; + key.m_en_face_name = en_prefered_face_name; + key.m_en_face_name.TrimLeftAndRight(); key.m_font_weight = prefered_weight; key.m_font_stretch = prefered_stretch; @@ -4748,11 +4827,17 @@ const ON_Font* ON_FontList::FromFontProperties( bool bRequireStyleMatch ) const { - return FromNames( + ON_wString en_fam_name = font_properties->FamilyName(ON_Font::NameLocale::English); + ON_wString en_face_name = font_properties->FaceName(ON_Font::NameLocale::English); + ON_wString en_win_log_font_name = font_properties->WindowsLogfontName(ON_Font::NameLocale::English); + return FromNames2( font_properties->PostScriptName(m_name_locale), font_properties->WindowsLogfontName(m_name_locale), + en_win_log_font_name, font_properties->FamilyName(m_name_locale), + en_fam_name, font_properties->FaceName(m_name_locale), + en_face_name, font_properties->FontWeight(), font_properties->FontStretch(), font_properties->FontStyle(), @@ -5714,7 +5799,9 @@ bool ON_Font::IsInstalledFont() const bool ON_Font::IsManagedInstalledFont() const { const ON__UINT_PTR bits = 3; - return IsManagedFont() && (1 == (m_managed_installed_font_and_bits & bits)); + bool ism = IsManagedFont(); + //return IsManagedFont() && (1 == (m_managed_installed_font_and_bits & bits)); + return ism && (1 == (m_managed_installed_font_and_bits & bits)); } bool ON_Font::IsManagedSubstitutedFont() const @@ -6340,6 +6427,9 @@ void ON_Font::Internal_CopyFrom( m_logfont_charset = src.m_logfont_charset; m_locale_name = src.m_locale_name; + if (!m_locale_name.EqualOrdinal(L"en-US", true) && !m_locale_name.EqualOrdinal(L"", true)) { + m_locale_name = "ja-JP"; + } m_loc_postscript_name = src.m_loc_postscript_name; m_en_postscript_name = src.m_en_postscript_name; @@ -10341,6 +10431,9 @@ ON_Font::ON_Font( m_font_origin = ON_Font::Origin::WindowsFont; m_locale_name = dwrite_font_information.m_prefered_locale; + if (!m_locale_name.EqualOrdinal(L"en-US", true) && !m_locale_name.EqualOrdinal(L"", true)) { + m_locale_name = "ja-JP"; + } m_loc_postscript_name = dwrite_font_information.m_loc_postscript_name; m_en_postscript_name = dwrite_font_information.m_en_postscript_name; diff --git a/opennurbs_font.h b/opennurbs_font.h index 2c320774..5af021aa 100644 --- a/opennurbs_font.h +++ b/opennurbs_font.h @@ -6606,6 +6606,42 @@ private: double point_size ) const; +private: + const ON_Font* FromNames2( + const wchar_t* postscript_name, + const wchar_t* windows_logfont_name, + const wchar_t* en_windows_logfont_name, + const wchar_t* family_name, + const wchar_t* en_family_name, + const wchar_t* prefered_face_name, + const wchar_t* en_prefered_face_name, + ON_Font::Weight prefered_weight, + ON_Font::Stretch prefered_stretch, + ON_Font::Style prefered_style, + bool bRequireFaceMatch, + bool bRequireStyleMatch + ) const; + +private: + const ON_Font* Internal_FromNames2( + const wchar_t* postscript_name, + const wchar_t* windows_logfont_name, + const wchar_t* en_windows_logfont_name, + const wchar_t* family_name, + const wchar_t* en_family_name, + const wchar_t* prefered_face_name, + const wchar_t* en_prefered_face_name, + ON_Font::Weight prefered_weight, + ON_Font::Stretch prefered_stretch, + ON_Font::Style prefered_style, + bool bRequireFaceMatch, + bool bRequireStyleMatch, + bool bMatchUnderlineStrikethroughAndPointSize, + bool bUnderlined, + bool bStrikethrough, + double point_size + ) const; + private: const ON_Font::NameLocale m_name_locale = ON_Font::NameLocale::LocalizedFirst; bool m_bMatchUnderlineStrikethroughAndPointSize = false; diff --git a/opennurbs_fpoint.h b/opennurbs_fpoint.h index 5e147ab1..77922e98 100644 --- a/opennurbs_fpoint.h +++ b/opennurbs_fpoint.h @@ -168,6 +168,7 @@ public: void Set(float,float); double DistanceTo( const ON_2fPoint& ) const; + double DistanceToSquared(const ON_2fPoint&) const; int MaximumCoordinateIndex() const; double MaximumCoordinate() const; // absolute value of maximum coordinate @@ -352,6 +353,7 @@ public: void Set(float,float,float); double DistanceTo( const ON_3fPoint& ) const; + double DistanceToSquared(const ON_3fPoint&) const; int MaximumCoordinateIndex() const; double MaximumCoordinate() const; // absolute value of maximum coordinate diff --git a/opennurbs_intersect.cpp b/opennurbs_intersect.cpp index 9f2d1db5..385d8358 100644 --- a/opennurbs_intersect.cpp +++ b/opennurbs_intersect.cpp @@ -16,6 +16,7 @@ #include "opennurbs.h" + #if !defined(ON_COMPILING_OPENNURBS) // This check is included in all opennurbs source .c and .cpp files to insure // ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled. @@ -847,15 +848,15 @@ int ON_Intersect( double d1, d0 = line_point0.DistanceTo(circle_point0); if ( xcnt == 2 ) { - line_point1 = line.PointAt(*line_t1); - circle_point1 = circle.ClosestPointTo(line_point1); - d1 = line_point1.DistanceTo(circle_point1); + line_point1 = line.PointAt(*line_t1); + circle_point1 = circle.ClosestPointTo(line_point1); + d1 = line_point1.DistanceTo(circle_point1); } else { - line_point1 = line_point0; - circle_point1 = circle_point0; - d1 = d0; + line_point1 = line_point0; + circle_point1 = circle_point0; + d1 = d0; } if ( xcnt==2 && (d0 > tol && d1 > tol) ) { @@ -882,56 +883,283 @@ int ON_Intersect( return xcnt; } -int ON_Intersect( - const ON_Plane& plane, - const ON_Circle& circle, - ON_3dPoint& point0, - ON_3dPoint& point1 +int ON_Intersect( + const ON_Plane& plane, + const ON_Circle& circle, + ON_3dPoint& point0, + ON_3dPoint& point1 ) { - int rval = -1; - ON_Line xline; + int rval = -1; + ON_Line xline; double a,b; - bool rc = ON_Intersect(plane, circle.Plane(), xline); + bool rc = ON_Intersect(plane, circle.Plane(), xline); if(rc) - { - rval = ON_Intersect(xline, circle, &a, point0, &b, point1); - } - else - { + { + rval = ON_Intersect(xline, circle, &a, point0, &b, point1); + } + else + { double d = plane.plane_equation.ValueAt( circle.Center() ); if(d 1 - costol); // todo pretty loose and insensitive + bool coplanar = parallel && (C0.plane.DistanceTo(C1.plane.origin) < abstol); + if (coplanar) + { + const ON_Circle* C[2] = { &C0, &C1 }; + if (C1.Radius() >= C0.Radius()) + { + C[0] = &C1; + C[1] = &C0; + } + double R0 = C[0]->Radius(); // largest radius + double R1 = C[1]->Radius(); + + ON_3dVector D = C[1]->Center() - C[0]->Center(); + double d = D.Length(); + + if (d > abstol) + { + D.Unitize(); + ON_3dVector Dperp = ON_CrossProduct(D, C[0]->Normal()); + + if (d > R0 + R1 + abstol) + xcnt = 0; // disks are disjoint + else if (d + R1 + abstol < R0) + xcnt = 0; // small disk is in interior of large disk + else + { + double d1 = (R0 * R0 - R1 * R1 + d * d) / (2 * d); + double a1 = R0 * R0 - d1 * d1; + if (a1 < 0) + a1 = 0; + + a1 = sqrt(a1); + + if (a1 < .5 * abstol) + { + xcnt = 1; + P0 = C[0]->Center() + d1 * D; + } + else + { + xcnt = 2; + P0 = C[0]->Center() + d1 * D + a1 * Dperp; + P1 = C[0]->Center() + d1 * D - a1 * Dperp; + } + } + } + else if (R0 - R1 < abstol) + xcnt = 3; + else + xcnt = 0; + } + else if (!parallel) + { + ON_Line PxP; + if (ON_Intersect(C0.plane, C1.plane, PxP)) + { + ON_3dPoint CxL[2][2]; + + double t0, t1; + int x0 = ON_Intersect( PxP, C0, &t0, CxL[0][0], &t1, CxL[0][1] ); + int x1 = ON_Intersect( PxP, C1, &t0, CxL[1][0], &t1, CxL[1][1] ); + xcnt = 0; + for (int i = 0; i < x0; i++) + { + int j; + for (j = 0; j < x1; j++) + { + if(ON_PointsAreCoincident(3,false,CxL[0][i], CxL[1][j])) + break; + } + if (j < x1) + { + (xcnt?P0:P1) = CxL[0][i]; + xcnt++; + } + } + + } + } + return xcnt; +} + + + +int ON_Intersect( + const ON_Arc& A0, + const ON_Arc& A1, + ON_3dPoint& P0, + ON_3dPoint& P1) +{ + P0 = P1 = ON_3dPoint::UnsetPoint; + ON_3dPoint* P[] = { &P0, &P1 }; + int xcnt = 0; + + const double costol = ON_ZERO_TOLERANCE; + double scale0 = A0.MaximumCoordinate(); + double abstol = A1.MaximumCoordinate(); + if (abstol < scale0) + abstol = scale0; + abstol *= ON_RELATIVE_TOLERANCE; + if (abstol < ON_ZERO_TOLERANCE) + abstol = ON_ZERO_TOLERANCE; + + + ON_3dPoint CCX[2]; + int cxcnt = ON_Intersect(static_cast(A0), static_cast(A1), CCX[0], CCX[1]); + if ( cxcnt < 3) + { + for (int i = 0; i < cxcnt; i++) + { + double t; + if (A0.ClosestPointTo(CCX[i], &t)) + { + if (CCX[i].DistanceTo(A0.PointAt(t)) < abstol) + { + if (A1.ClosestPointTo(CCX[i], &t)) + { + if (CCX[i].DistanceTo(A1.PointAt(t)) < abstol) + *P[xcnt++] = CCX[i]; + } + } + } + } + } + else if (cxcnt == 3) + { + // circle doesn't degenerate to a point + // order arcs by size + const ON_Arc* Size[] = { &A0, &A1 }; //Size[0]<=Size[1] + if (A0.Domain().Length() > A1.Domain().Length()) + { + Size[0] = &A1; + Size[1] = &A0; + } + + // Match ends of smaller to larger arc + double LittleEndMatch[2]; // relative to Big ArcBig, 0-start, 1-end , .5 (interior), -1 ( exterior) + + ON_Interval BigInterior = Size[1]->Domain(); // interior domain of big arc + if (!BigInterior.Expand(-abstol / Size[1]->Radius())) // circles are not degenerate + BigInterior = ON_Interval::Singleton(Size[1]->Domain().Mid()); + + for (int ei = 0; ei < 2; ei++) + { + double t; + ON_3dPoint LittleEnd = ei ? Size[0]->EndPoint() : Size[0]->StartPoint(); + if (Size[1]->ClosestPointTo(LittleEnd, &t)) + { + switch (BigInterior.Clamp(t)) + { + case(-1): + if (Size[1]->StartPoint().DistanceTo(LittleEnd) < abstol) + LittleEndMatch[ei] = 0; // start + else + LittleEndMatch[ei] = -1; // exterior + break; + case(0): + LittleEndMatch[ei] = .5; // interior + break; + case(1): + if (Size[1]->EndPoint().DistanceTo(LittleEnd) < abstol) + LittleEndMatch[ei] = 1; // end + else + LittleEndMatch[ei] = -1; // exterior + break; + } + } + } + + if (LittleEndMatch[0] == .5 || LittleEndMatch[1] == .5) + xcnt = 3; // an interior match means an overlap + else if (LittleEndMatch[0] == -1 && LittleEndMatch[1] == -1) + xcnt = 0; // both points exterior means intersection is empty + else if (LittleEndMatch[0] == -1) + *P[xcnt++] = Size[0]->EndPoint(); // if start is exterior end must be an intersection point + else if (LittleEndMatch[1] == -1) + *P[xcnt++] = Size[0]->StartPoint(); + else + { + // Both endpoints match endpoints of Big + // LittleEndMatch[ei] \in { 0, 1 } + bool Orientation_agree = (A0.Normal() * A1.Normal() > 0); // true if the orientations agree + if (LittleEndMatch[0] != LittleEndMatch[1]) + { + if (Orientation_agree == (LittleEndMatch[0] == 1.0)) + { + *P[xcnt++] = Size[0]->StartPoint(); + *P[xcnt++] = Size[0]->EndPoint(); + } + else + xcnt = 3; + } + else + { + // Degenerate cases + if (Size[0]->StartPoint().DistanceTo(Size[0]->EndPoint()) < abstol) + *P[xcnt++] = Size[0]->StartPoint(); + else + xcnt = 3; + } + } + } + + return xcnt; } int ON_Intersect( diff --git a/opennurbs_math.h b/opennurbs_math.h index c82aca09..d6e6afe2 100644 --- a/opennurbs_math.h +++ b/opennurbs_math.h @@ -1881,6 +1881,49 @@ int ON_Intersect( ); +// Description: +// Intersect a pair of circles +// Parameters: +// circle0 - [in] +// circle11 - [in] +// point0 - [out] first intersection point +// point1 - [out] second intersection point +// Returns: +// 0 No intersection +// 1 One intersection at point0 +// 2 Two intersections at point0 +// and point1. +// 3 Circles are identical +ON_DECL +int ON_Intersect( + const ON_Circle& c0, + const ON_Circle& c1, + ON_3dPoint& point0, + ON_3dPoint& point1 +); + + +// Description: +// Intersect a pair of arcs, note either arc could be a full circle +// Parameters: +// arc0 - [in] +// arc1 - [in] +// point0 - [out] first intersection point +// point1 - [out] second intersection point +// Returns: +// 0 No intersection +// 1 One intersection at point0 +// 2 Two intersections at point0 +// and point1. +// 3 arcs are cocircular and overlap +ON_DECL +int ON_Intersect( + const ON_Arc& arc0, + const ON_Arc& arc1, + ON_3dPoint& point0, + ON_3dPoint& point1 +); + // returns 0 = no, 1 = yes, 2 = points are coincident and on line ON_DECL int ON_ArePointsOnLine( @@ -2260,6 +2303,14 @@ Returns: */ ON_DECL double ON_Length2d( double x, double y ); +/* +Descripton: + Return the squared length of a 2d vector (x,y) +Returns: + (x^2 + y^2) +*/ +ON_DECL double ON_Length2dSquared(double x, double y); + /* Descripton: Return the length of a 3d vector (x,y,z) @@ -2268,6 +2319,13 @@ Returns: */ ON_DECL double ON_Length3d( double x, double y, double z ); +/* +Descripton: + Return the squared length of a 3d vector (x,y,z) +Returns: + (x^2 + y^2 + z^2) +*/ +ON_DECL double ON_Length3dSquared(double x, double y, double z); /* Description: diff --git a/opennurbs_mesh.cpp b/opennurbs_mesh.cpp index 44428ae8..c7c78cb2 100644 --- a/opennurbs_mesh.cpp +++ b/opennurbs_mesh.cpp @@ -14831,9 +14831,7 @@ bool ON_MeshCache::Transform( ON_Mesh* mesh = item->m_mesh_sp.get(); if (nullptr == mesh || mesh->IsEmpty()) continue; - // NOTE: use_count() == 1 is an approximation in multi-threaded environments - // https:// en.cppreference.com/w/cpp/memory/shared_ptr/unique - if (item->m_mesh_sp.use_count() != 1) + if (false == item->m_mesh_sp.unique()) { // make a copy and transform the copy std::shared_ptr(new ON_Mesh(*mesh)).swap(item->m_mesh_sp); diff --git a/opennurbs_object_history.cpp b/opennurbs_object_history.cpp index a3d06de4..468b12c6 100644 --- a/opennurbs_object_history.cpp +++ b/opennurbs_object_history.cpp @@ -2937,6 +2937,22 @@ void ON_HistoryRecord::RemapObjectIds( const ON_SimpleArray& id_rem uuid_v->m_value[j] = id_remap[index].m_uuid[1]; } } + // 27 Oct 2021, Mikko, RH-66102: + // Polyedge values contain objrefs and also need remapping. + // This fixes history replay not working properly on BlendSrf and others + // when importing/pasting. + else if (v && ON_Value::polyedge_value == v->m_value_type) + { + ON_PolyEdgeHistoryValue* objrev_v = static_cast(v); + for (j = 0; j < objrev_v->m_value.Count(); j++) + { + int k; + for (k = 0; k < objrev_v->m_value[j].m_segment.Count(); k++) + { + objrev_v->m_value[j].m_segment[k].m_curve_ref.RemapObjectId(id_remap); + } + } + } } } } diff --git a/opennurbs_point.cpp b/opennurbs_point.cpp index b4423387..deb0ce93 100644 --- a/opennurbs_point.cpp +++ b/opennurbs_point.cpp @@ -2284,6 +2284,11 @@ double ON_2fPoint::DistanceTo( const ON_2fPoint& p ) const return ON_Length2d(p.x-x,p.y-y); } +double ON_2fPoint::DistanceToSquared(const ON_2fPoint& p) const +{ + return ON_Length2dSquared(p.x - x, p.y - y); +} + int ON_2fPoint::MaximumCoordinateIndex() const { return (fabs(y)>fabs(x)) ? 1 : 0; @@ -2723,6 +2728,11 @@ double ON_3fPoint::DistanceTo( const ON_3fPoint& p ) const return ON_Length3d(p.x-x,p.y-y,p.z-z); } +double ON_3fPoint::DistanceToSquared(const ON_3fPoint& p) const +{ + return ON_Length3dSquared(p.x - x, p.y - y, p.z - z); +} + int ON_3fPoint::MaximumCoordinateIndex() const { return (fabs(y)>fabs(x)) ? ((fabs(z)>fabs(y))?2:1) : ((fabs(z)>fabs(x))?2:0); @@ -4496,6 +4506,11 @@ double ON_2dPoint::DistanceTo( const ON_2dPoint& p ) const return ON_Length2d(p.x-x,p.y-y); } +double ON_2dPoint::DistanceToSquared(const ON_2dPoint& p) const +{ + return ON_Length2dSquared(p.x - x, p.y - y); +} + int ON_2dPoint::MaximumCoordinateIndex() const { return (fabs(y)>fabs(x)) ? 1 : 0; @@ -4953,6 +4968,11 @@ double ON_3dPoint::DistanceTo( const ON_3dPoint& p ) const return ON_Length3d(p.x-x,p.y-y,p.z-z); } +double ON_3dPoint::DistanceToSquared(const ON_3dPoint& p) const +{ + return ON_Length3dSquared(p.x - x, p.y - y, p.z - z); +} + int ON_3dPoint::MaximumCoordinateIndex() const { return (fabs(y)>fabs(x)) ? ((fabs(z)>fabs(y))?2:1) : ((fabs(z)>fabs(x))?2:0); @@ -5803,6 +5823,11 @@ double ON_Length2d( double x, double y ) return len; } +double ON_Length2dSquared(double x, double y) +{ + return (x * x + y * y); +} + double ON_2dVector::Length() const { return ON_Length2d(x,y); @@ -6409,6 +6434,11 @@ double ON_Length3d(double x, double y, double z) return len; } +double ON_Length3dSquared(double x, double y, double z) +{ + return (x * x + y * y + z * z); +} + double ON_3dVector::Length() const { return ON_Length3d(x,y,z); diff --git a/opennurbs_point.h b/opennurbs_point.h index 22b726ce..4f34bbfa 100644 --- a/opennurbs_point.h +++ b/opennurbs_point.h @@ -469,6 +469,7 @@ public: void Set(double x,double y); double DistanceTo( const ON_2dPoint& ) const; + double DistanceToSquared(const ON_2dPoint&) const; int MaximumCoordinateIndex() const; double MaximumCoordinate() const; // absolute value of maximum coordinate @@ -675,6 +676,7 @@ public: void Set(double x,double y,double z); double DistanceTo( const ON_3dPoint& ) const; + double DistanceToSquared(const ON_3dPoint&) const; int MaximumCoordinateIndex() const; double MaximumCoordinate() const; // absolute value of maximum coordinate diff --git a/opennurbs_polylinecurve.cpp b/opennurbs_polylinecurve.cpp index 4847af55..a439248c 100644 --- a/opennurbs_polylinecurve.cpp +++ b/opennurbs_polylinecurve.cpp @@ -172,7 +172,8 @@ ON_PolylineCurve::SwapCoordinates( int i, int j ) bool ON_PolylineCurve::IsValid( ON_TextLog* text_log ) const { const int count = PointCount(); - if ( count >= 2 && count == m_t.Count() ) + bool rc = (count >= 2 && count == m_t.Count()); + if (rc) { if ( !m_pline.IsValid() ) { @@ -213,7 +214,7 @@ bool ON_PolylineCurve::IsValid( ON_TextLog* text_log ) const return ON_IsNotValid(); } - return true; + return rc; } void ON_PolylineCurve::Dump( ON_TextLog& dump ) const diff --git a/opennurbs_public_version.h b/opennurbs_public_version.h index f0462c07..1665b68c 100644 --- a/opennurbs_public_version.h +++ b/opennurbs_public_version.h @@ -6,17 +6,17 @@ // To update version numbers, edit ..\build\build_dates.msbuild #define RMA_VERSION_MAJOR 7 -#define RMA_VERSION_MINOR 11 +#define RMA_VERSION_MINOR 14 //////////////////////////////////////////////////////////////// // // These are set automatically by the build system as the // first step in each build. // -#define RMA_VERSION_YEAR 2021 -#define RMA_VERSION_MONTH 10 -#define RMA_VERSION_DATE 12 -#define RMA_VERSION_HOUR 13 +#define RMA_VERSION_YEAR 2022 +#define RMA_VERSION_MONTH 1 +#define RMA_VERSION_DATE 10 +#define RMA_VERSION_HOUR 17 #define RMA_VERSION_MINUTE 0 //////////////////////////////////////////////////////////////// @@ -35,20 +35,20 @@ // 3 = build system release build #define RMA_VERSION_BRANCH 0 -#define VERSION_WITH_COMMAS 7,11,21285,13000 -#define VERSION_WITH_PERIODS 7.11.21285.13000 -#define COPYRIGHT "Copyright (C) 1993-2021, Robert McNeel & Associates. All Rights Reserved." +#define VERSION_WITH_COMMAS 7,14,22010,17000 +#define VERSION_WITH_PERIODS 7.14.22010.17000 +#define COPYRIGHT "Copyright (C) 1993-2022, Robert McNeel & Associates. All Rights Reserved." #define SPECIAL_BUILD_DESCRIPTION "Public OpenNURBS C++ 3dm file IO library." #define RMA_VERSION_NUMBER_MAJOR_STRING "7" #define RMA_VERSION_NUMBER_MAJOR_WSTRING L"7" #define RMA_PREVIOUS_VERSION_NUMBER_MAJOR_WSTRING L"6" -#define RMA_VERSION_NUMBER_SR_STRING "SR11" -#define RMA_VERSION_NUMBER_SR_WSTRING L"SR11" +#define RMA_VERSION_NUMBER_SR_STRING "SR14" +#define RMA_VERSION_NUMBER_SR_WSTRING L"SR14" -#define RMA_VERSION_WITH_PERIODS_STRING "7.11.21285.13000" -#define RMA_VERSION_WITH_PERIODS_WSTRING L"7.11.21285.13000" +#define RMA_VERSION_WITH_PERIODS_STRING "7.14.22010.17000" +#define RMA_VERSION_WITH_PERIODS_WSTRING L"7.14.22010.17000" diff --git a/opennurbs_string_value.h b/opennurbs_string_value.h index b84e1d07..95b712cc 100644 --- a/opennurbs_string_value.h +++ b/opennurbs_string_value.h @@ -432,7 +432,7 @@ public: private: // parsing context unsigned int m_context_locale_id = 0; - ON::LengthUnitSystem m_context_length_unit_system = ON::LengthUnitSystem::None; + ON::LengthUnitSystem m_context_length_unit_system; ON_AngleValue::StringFormat m_string_format = ON_AngleValue::StringFormat::ExactDecimal; ON::AngleUnitSystem m_angle_unit_system = ON::AngleUnitSystem::Unset; diff --git a/opennurbs_system_compiler.h b/opennurbs_system_compiler.h index 84ccd97d..c03e7694 100644 --- a/opennurbs_system_compiler.h +++ b/opennurbs_system_compiler.h @@ -235,6 +235,8 @@ // ///////////////////////////////////////////////////////////////////////////////////// +#define ON_CLANG_CONSTRUCTOR_BUG + #endif #endif @@ -273,6 +275,33 @@ #define ON_PRAGMA_WARNING_POP clang diagnostic pop // Apple CLang warning state pop #define ON_PRAGMA_WARNING_DISABLE_CLANG(ON_PRAGMA_WARNING_DISABLE_param) clang diagnostic ignored ON_PRAGMA_WARNING_DISABLE_param // Apple CLang warning disable +// clang has a bug that is fails to correctly construct statc const objects +// in the following case +// +// // header file +// class Blah +// { +// public: +// Blah() = default; +// ~Blah() = default; +// Blah(const Blah&) = default; +// Blah& operator=(const Blah&) = default; +// +// static const Blah Zero; +// +// int m_i = 0; +// }; +// +// ... +// +// // cpp file +// const Blah Blah::Zero; // correct C++ 11, Apple's clang fails as of February, 2015 +// const Blah Blah::Zero( Blah() ); // clang fails to use copy constructor +// const Blah Blah::Zero = Blah(); // clang can handle this +// +// When this bug is fixed, delete this define and the places +// in the code that use it. +#define ON_CLANG_CONSTRUCTOR_BUG #if defined(__has_feature) && __has_feature(cxx_noexcept) #undef ON_NOEXCEPT diff --git a/opennurbs_textcontext.cpp b/opennurbs_textcontext.cpp index 967cbe9e..e53d0885 100644 --- a/opennurbs_textcontext.cpp +++ b/opennurbs_textcontext.cpp @@ -281,10 +281,17 @@ bool ON_TextContent::GetRichTextFontTable( int font_pos = rich_text.Find(L"\\f", i); if (font_pos > i) { + bool pos_passed_fnumber = false; + int fnumber_len = 2; // the \f for (int j = font_pos + 2; j < table_len; j++) { - if (rtf[j] == L' ') + if (rtf[j] != L' ' && !pos_passed_fnumber) { + fnumber_len++; + } + else + { + pos_passed_fnumber = true; for (int si = 0; si + j < table_len; si++) { if (rich_text[si + j] != L' ') @@ -297,7 +304,11 @@ bool ON_TextContent::GetRichTextFontTable( { if (rtf[ni + j] == L';' || rtf[ni + j] == L'}') { - font_table.AppendNew() = rich_text.SubString(j, ni); + ON_wString fn = ON_wString(rich_text.SubString(font_pos, fnumber_len)); + // only add the font if it's actually used in the rtf string + if (rich_text.Find(fn, table_len) != -1) { + font_table.AppendNew() = rich_text.SubString(j, ni); + } i = ni + j; j = len; break;