From 6486c64975e725f8eb5427af6e341967848e8ef3 Mon Sep 17 00:00:00 2001 From: Bozo The Builder Date: Tue, 6 Sep 2022 10:56:15 -0700 Subject: [PATCH] Sync changes from upstream repository Co-authored-by: Andrew le Bihan Co-authored-by: croudyj Co-authored-by: Dale Fugier Co-authored-by: Dan Rigdon-Bel Co-authored-by: Greg Arden Co-authored-by: Jussi Aaltonen Co-authored-by: kike-garbo Co-authored-by: piac Co-authored-by: Steve Baer Co-authored-by: Will Pearson --- makefile | 6 +- opennurbs.h | 8 +- opennurbsRhino_iOS.xcodeproj/project.pbxproj | 22 +- opennurbs_3dm_attributes.cpp | 184 ++- opennurbs_3dm_attributes.h | 55 +- opennurbs_3dm_properties.h | 2 +- opennurbs_archivable_dictionary.cpp | 1346 ++++++++++++++++++ opennurbs_archivable_dictionary.h | 155 ++ opennurbs_archive.cpp | 248 ++-- opennurbs_archive.h | 123 +- opennurbs_array.h | 22 +- opennurbs_bitmap.cpp | 4 + opennurbs_bounding_box.cpp | 14 +- opennurbs_brep_tools.cpp | 2 +- opennurbs_current_environment.cpp | 192 --- opennurbs_current_environment.h | 58 - opennurbs_decals.cpp | 425 ++---- opennurbs_decals.h | 20 +- opennurbs_defines.cpp | 36 +- opennurbs_dithering.cpp | 4 +- opennurbs_embedded_file.cpp | 10 +- opennurbs_extensions.cpp | 266 ++-- opennurbs_extensions.h | 38 +- opennurbs_font.cpp | 2 +- opennurbs_internal_defines.h | 87 +- opennurbs_light.cpp | 4 +- opennurbs_linear_workflow.cpp | 4 +- opennurbs_material.cpp | 33 +- opennurbs_mesh_modifiers.cpp | 1085 ++++++++++---- opennurbs_mesh_modifiers.h | 339 ++++- opennurbs_nurbscurve.cpp | 6 +- opennurbs_polylinecurve.cpp | 16 + opennurbs_polylinecurve.h | 9 + opennurbs_post_effects.cpp | 4 + opennurbs_public.vcxproj | 4 +- opennurbs_public.xcodeproj/project.pbxproj | 8 - opennurbs_public_staticlib.vcxproj | 4 +- opennurbs_public_version.h | 14 +- opennurbs_render_channels.cpp | 12 +- opennurbs_render_content.cpp | 64 +- opennurbs_sha1.cpp | 7 + opennurbs_sha1.h | 4 + opennurbs_string_compare.cpp | 4 +- opennurbs_subd.cpp | 2 +- opennurbs_sun.cpp | 36 +- opennurbs_symmetry.cpp | 2 +- opennurbs_system.h | 111 +- opennurbs_system_compiler.h | 14 + opennurbs_xml.cpp | 105 +- opennurbs_xml.h | 34 +- opennurbs_zlib.cpp | 24 +- 51 files changed, 3785 insertions(+), 1493 deletions(-) create mode 100644 opennurbs_archivable_dictionary.cpp create mode 100644 opennurbs_archivable_dictionary.h delete mode 100644 opennurbs_current_environment.cpp delete mode 100644 opennurbs_current_environment.h diff --git a/makefile b/makefile index d33ce49b..aa43144c 100644 --- a/makefile +++ b/makefile @@ -81,6 +81,7 @@ ON_INC = opennurbs.h \ opennurbs_annotationbase.h \ opennurbs_arc.h \ opennurbs_arccurve.h \ + opennurbs_archivable_dictionary.h \ opennurbs_archive.h \ opennurbs_array.h \ opennurbs_array_defs.h \ @@ -98,7 +99,6 @@ ON_INC = opennurbs.h \ opennurbs_compstat.h \ opennurbs_cone.h \ opennurbs_crc.h \ - opennurbs_current_environment.h \ opennurbs_curve.h \ opennurbs_curveonsurface.h \ opennurbs_curveproxy.h \ @@ -243,6 +243,7 @@ ON_SRC = opennurbs_3dm_attributes.cpp \ opennurbs_annotationbase.cpp \ opennurbs_arc.cpp \ opennurbs_arccurve.cpp \ + opennurbs_archivable_dictionary.cpp \ opennurbs_archive.cpp \ opennurbs_archive_manifest.cpp \ opennurbs_array.cpp \ @@ -268,7 +269,6 @@ ON_SRC = opennurbs_3dm_attributes.cpp \ opennurbs_compstat.cpp \ opennurbs_cone.cpp \ opennurbs_crc.cpp \ - opennurbs_current_environment.cpp \ opennurbs_curve.cpp \ opennurbs_curveonsurface.cpp \ opennurbs_curveproxy.cpp \ @@ -433,6 +433,7 @@ ON_OBJ = opennurbs_3dm_attributes.o \ opennurbs_annotationbase.o \ opennurbs_arc.o \ opennurbs_arccurve.o \ + opennurbs_archivable_dictionary.o \ opennurbs_archive.o \ opennurbs_archive_manifest.o \ opennurbs_array.o \ @@ -458,7 +459,6 @@ ON_OBJ = opennurbs_3dm_attributes.o \ opennurbs_compstat.o \ opennurbs_cone.o \ opennurbs_crc.o \ - opennurbs_current_environment.o \ opennurbs_curve.o \ opennurbs_curveonsurface.o \ opennurbs_curveproxy.o \ diff --git a/opennurbs.h b/opennurbs.h index 37d356a6..68638bb9 100644 --- a/opennurbs.h +++ b/opennurbs.h @@ -135,6 +135,10 @@ #include "opennurbs_brep.h" // boundary rep #include "opennurbs_beam.h" // lightweight extrusion object #include "opennurbs_subd.h" // subdivison surface object + +#include "opennurbs_xml.h" // XML classes. +#include "opennurbs_decals.h" // Decal support. + #include "opennurbs_bitmap.h" // Windows and OpenGL bitmaps #include "opennurbs_instance.h" // instance definitions and references #include "opennurbs_3dm_properties.h" @@ -161,9 +165,8 @@ #include "opennurbs_dimension.h" #include "opennurbs_dimensionformat.h" // Formatting dimension measurements to strings #include "opennurbs_photogrammetry.h" +#include "opennurbs_archivable_dictionary.h" -#include "opennurbs_xml.h" // XML classes. -#include "opennurbs_current_environment.h" // Current Environment support. #include "opennurbs_dithering.h" // Dithering support. #include "opennurbs_embedded_file.h" // Embedded file support. #include "opennurbs_ground_plane.h" // Ground Plane support. @@ -174,7 +177,6 @@ #include "opennurbs_skylight.h" // Skylight support. #include "opennurbs_sun.h" // Sun support. #include "opennurbs_post_effects.h" // Post Effect support. -#include "opennurbs_decals.h" // Decal support. #include "opennurbs_mesh_modifiers.h" // Mesh Modifiers support. #include "opennurbs_extensions.h" #include "opennurbs_freetype.h" diff --git a/opennurbsRhino_iOS.xcodeproj/project.pbxproj b/opennurbsRhino_iOS.xcodeproj/project.pbxproj index 280a0191..737950eb 100644 --- a/opennurbsRhino_iOS.xcodeproj/project.pbxproj +++ b/opennurbsRhino_iOS.xcodeproj/project.pbxproj @@ -300,6 +300,9 @@ 992E4E2128217D9A00033A20 /* opennurbs_decals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 992E4E1D28217D9A00033A20 /* opennurbs_decals.cpp */; }; 992E4E2628217DB700033A20 /* opennurbs_decals.h in Headers */ = {isa = PBXBuildFile; fileRef = 992E4E2328217DB700033A20 /* opennurbs_decals.h */; }; 992E4E2728217DB700033A20 /* opennurbs_decals.h in Headers */ = {isa = PBXBuildFile; fileRef = 992E4E2328217DB700033A20 /* opennurbs_decals.h */; }; + 997CC53228AEA75900E18BDB /* opennurbs_archivable_dictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 997CC52F28AEA75800E18BDB /* opennurbs_archivable_dictionary.h */; }; + 997CC53428AEA76600E18BDB /* opennurbs_archivable_dictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 997CC53328AEA76600E18BDB /* opennurbs_archivable_dictionary.cpp */; }; + 997CC53528AEA8AB00E18BDB /* opennurbs_archivable_dictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 997CC53328AEA76600E18BDB /* opennurbs_archivable_dictionary.cpp */; }; 99B39379284A90C4000FCE50 /* opennurbs_mesh_modifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = 99B39376284A90C4000FCE50 /* opennurbs_mesh_modifiers.h */; }; 99B3937B284A90D9000FCE50 /* opennurbs_mesh_modifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99B3937A284A90D9000FCE50 /* opennurbs_mesh_modifiers.cpp */; }; 99B3937C284A90DF000FCE50 /* opennurbs_mesh_modifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99B3937A284A90D9000FCE50 /* opennurbs_mesh_modifiers.cpp */; }; @@ -325,8 +328,6 @@ A165DF1527D1DFD10006F184 /* opennurbs_linear_workflow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A165DF1127D1DFD10006F184 /* opennurbs_linear_workflow.cpp */; }; A165DF1A27D1DFE10006F184 /* opennurbs_linear_workflow.h in Headers */ = {isa = PBXBuildFile; fileRef = A165DF1727D1DFE10006F184 /* opennurbs_linear_workflow.h */; }; A165DF1B27D1DFE10006F184 /* opennurbs_linear_workflow.h in Headers */ = {isa = PBXBuildFile; fileRef = A165DF1727D1DFE10006F184 /* opennurbs_linear_workflow.h */; }; - A1C9656727FCBF7F006A1C3E /* opennurbs_current_environment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1C9656127FCBF7F006A1C3E /* opennurbs_current_environment.cpp */; }; - A1C9656827FCBF7F006A1C3E /* opennurbs_current_environment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1C9656127FCBF7F006A1C3E /* opennurbs_current_environment.cpp */; }; A1C9656927FCBF7F006A1C3E /* opennurbs_sun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1C9656427FCBF7F006A1C3E /* opennurbs_sun.cpp */; }; A1C9656A27FCBF7F006A1C3E /* opennurbs_sun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1C9656427FCBF7F006A1C3E /* opennurbs_sun.cpp */; }; A1C9656B27FCBF7F006A1C3E /* opennurbs_skylight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1C9656527FCBF7F006A1C3E /* opennurbs_skylight.cpp */; }; @@ -337,8 +338,6 @@ A1C9657427FCBFB7006A1C3E /* opennurbs_skylight.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C9656F27FCBFB7006A1C3E /* opennurbs_skylight.h */; }; A1C9657527FCBFB7006A1C3E /* opennurbs_sun.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C9657027FCBFB7006A1C3E /* opennurbs_sun.h */; }; A1C9657627FCBFB7006A1C3E /* opennurbs_sun.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C9657027FCBFB7006A1C3E /* opennurbs_sun.h */; }; - A1C9657727FCBFB7006A1C3E /* opennurbs_current_environment.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C9657127FCBFB7006A1C3E /* opennurbs_current_environment.h */; }; - A1C9657827FCBFB7006A1C3E /* opennurbs_current_environment.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C9657127FCBFB7006A1C3E /* opennurbs_current_environment.h */; }; A1C9657927FCBFB7006A1C3E /* opennurbs_dithering.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C9657227FCBFB7006A1C3E /* opennurbs_dithering.h */; }; A1C9657A27FCBFB7006A1C3E /* opennurbs_dithering.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C9657227FCBFB7006A1C3E /* opennurbs_dithering.h */; }; D60201E71B11912300DBB04B /* opennurbs_dimensionstyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D60201E51B11912300DBB04B /* opennurbs_dimensionstyle.cpp */; }; @@ -1006,6 +1005,8 @@ 99284D042800FD4B00CA9E82 /* opennurbs_render_channels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_render_channels.h; sourceTree = ""; }; 992E4E1D28217D9A00033A20 /* opennurbs_decals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_decals.cpp; sourceTree = ""; }; 992E4E2328217DB700033A20 /* opennurbs_decals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_decals.h; sourceTree = ""; }; + 997CC52F28AEA75800E18BDB /* opennurbs_archivable_dictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_archivable_dictionary.h; sourceTree = ""; }; + 997CC53328AEA76600E18BDB /* opennurbs_archivable_dictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_archivable_dictionary.cpp; sourceTree = ""; }; 99B39376284A90C4000FCE50 /* opennurbs_mesh_modifiers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_mesh_modifiers.h; sourceTree = ""; }; 99B3937A284A90D9000FCE50 /* opennurbs_mesh_modifiers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_mesh_modifiers.cpp; sourceTree = ""; }; A165DEC527C952E70006F184 /* opennurbs_render_content.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_render_content.cpp; sourceTree = ""; }; @@ -1019,13 +1020,11 @@ A165DEFA27CF8B390006F184 /* opennurbs_ground_plane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_ground_plane.h; sourceTree = ""; }; A165DF1127D1DFD10006F184 /* opennurbs_linear_workflow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_linear_workflow.cpp; sourceTree = ""; }; A165DF1727D1DFE10006F184 /* opennurbs_linear_workflow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_linear_workflow.h; sourceTree = ""; }; - A1C9656127FCBF7F006A1C3E /* opennurbs_current_environment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_current_environment.cpp; sourceTree = ""; }; A1C9656427FCBF7F006A1C3E /* opennurbs_sun.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_sun.cpp; sourceTree = ""; }; A1C9656527FCBF7F006A1C3E /* opennurbs_skylight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_skylight.cpp; sourceTree = ""; }; A1C9656627FCBF7F006A1C3E /* opennurbs_dithering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_dithering.cpp; sourceTree = ""; }; A1C9656F27FCBFB7006A1C3E /* opennurbs_skylight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_skylight.h; sourceTree = ""; }; A1C9657027FCBFB7006A1C3E /* opennurbs_sun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_sun.h; sourceTree = ""; }; - A1C9657127FCBFB7006A1C3E /* opennurbs_current_environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_current_environment.h; sourceTree = ""; }; A1C9657227FCBFB7006A1C3E /* opennurbs_dithering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_dithering.h; sourceTree = ""; }; D2AAC046055464E500DB518D /* libopennurbs.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libopennurbs.a; sourceTree = BUILT_PRODUCTS_DIR; }; D60201E51B11912300DBB04B /* opennurbs_dimensionstyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_dimensionstyle.cpp; sourceTree = ""; }; @@ -1258,6 +1257,7 @@ 1DC2CFA220992B1700DC77C6 /* opennurbs_apple_nsfont.h */, 10D7D06C09E051850056FF9C /* opennurbs_arc.h */, 10D7D06D09E051850056FF9C /* opennurbs_arccurve.h */, + 997CC52F28AEA75800E18BDB /* opennurbs_archivable_dictionary.h */, 10D7D06E09E051850056FF9C /* opennurbs_archive.h */, 10D7D06F09E051850056FF9C /* opennurbs_array_defs.h */, 10D7D07009E051850056FF9C /* opennurbs_array.h */, @@ -1276,7 +1276,6 @@ 10D7D07809E051850056FF9C /* opennurbs_cone.h */, F8A96FD822949F2600C6FB6D /* opennurbs_convex_poly.h */, 10D7D07909E051850056FF9C /* opennurbs_crc.h */, - A1C9657127FCBFB7006A1C3E /* opennurbs_current_environment.h */, 10D7D07A09E051850056FF9C /* opennurbs_curve.h */, 10D7D07B09E051850056FF9C /* opennurbs_curveonsurface.h */, 10D7D07C09E051850056FF9C /* opennurbs_curveproxy.h */, @@ -1452,6 +1451,7 @@ 1DC2CFA620992B2900DC77C6 /* opennurbs_apple_nsfont.cpp */, 10D7CF8F09E04EA60056FF9C /* opennurbs_arc.cpp */, 10D7CF9009E04EA60056FF9C /* opennurbs_arccurve.cpp */, + 997CC53328AEA76600E18BDB /* opennurbs_archivable_dictionary.cpp */, D6B06A941BC57E52000B5948 /* opennurbs_archive_manifest.cpp */, 10D7CF9109E04EA60056FF9C /* opennurbs_archive.cpp */, 10D7CF9209E04EA60056FF9C /* opennurbs_array.cpp */, @@ -1478,7 +1478,6 @@ 10D7CFA209E04EA60056FF9C /* opennurbs_cone.cpp */, F8A96FD522949F2600C6FB6D /* opennurbs_convex_poly.cpp */, 10D7CFA309E04EA60056FF9C /* opennurbs_crc.cpp */, - A1C9656127FCBF7F006A1C3E /* opennurbs_current_environment.cpp */, 10D7CFA409E04EA60056FF9C /* opennurbs_curve.cpp */, 10D7CFA509E04EA60056FF9C /* opennurbs_curveonsurface.cpp */, 10D7CFA609E04EA60056FF9C /* opennurbs_curveproxy.cpp */, @@ -1870,7 +1869,6 @@ D65C796A1B0F9CA0004C745E /* opennurbs_function_list.h in Headers */, 10D7D11909E052650056FF9C /* opennurbs_textlog.h in Headers */, 10D7D11A09E052650056FF9C /* opennurbs_texture_mapping.h in Headers */, - A1C9657727FCBFB7006A1C3E /* opennurbs_current_environment.h in Headers */, D6184CC21B0F83560099E507 /* opennurbs_text.h in Headers */, D69DB7241A957CE80080DA91 /* opennurbs_subd.h in Headers */, 10D7D11B09E052650056FF9C /* opennurbs_texture.h in Headers */, @@ -1883,6 +1881,7 @@ 10D7D12009E052650056FF9C /* opennurbs_viewport.h in Headers */, 10D7D12109E052650056FF9C /* opennurbs_workspace.h in Headers */, 369B20161CE520B600A5CB6E /* opennurbs_textobject.h in Headers */, + 997CC53228AEA75900E18BDB /* opennurbs_archivable_dictionary.h in Headers */, D6184CC91B0F83560099E507 /* opennurbs_wip.h in Headers */, 10D7D12309E052650056FF9C /* opennurbs_xform.h in Headers */, D69DB7231A957CE80080DA91 /* opennurbs_subd_data.h in Headers */, @@ -1953,7 +1952,6 @@ 1D54D9C82388A2470053ECCD /* opennurbs_symmetry.h in Headers */, 992E4E2728217DB700033A20 /* opennurbs_decals.h in Headers */, 1DF230CF21CDC06900C49CBF /* opennurbs_plus_subd.h in Headers */, - A1C9657827FCBFB7006A1C3E /* opennurbs_current_environment.h in Headers */, A165DED327C953020006F184 /* opennurbs_render_content.h in Headers */, A165DEEE27CF88B00006F184 /* opennurbs_safe_frame.h in Headers */, F8A96FDC22949F2600C6FB6D /* opennurbs_convex_poly.h in Headers */, @@ -2157,6 +2155,7 @@ 10D7CFBF09E04EA60056FF9C /* opennurbs_circle.cpp in Sources */, D66DBDAF1A67505A00125759 /* opennurbs_parse_point.cpp in Sources */, 10D7CFC009E04EA60056FF9C /* opennurbs_color.cpp in Sources */, + 997CC53428AEA76600E18BDB /* opennurbs_archivable_dictionary.cpp in Sources */, 10D7CFC109E04EA60056FF9C /* opennurbs_cone.cpp in Sources */, 10D7CFC209E04EA60056FF9C /* opennurbs_crc.cpp in Sources */, D66DBDAB1A67505A00125759 /* opennurbs_mesh_topology.cpp in Sources */, @@ -2265,7 +2264,6 @@ 10D7D05609E04F820056FF9C /* opennurbs_torus.cpp in Sources */, 10D7D05709E04F820056FF9C /* opennurbs_userdata.cpp in Sources */, 10D7D05809E04F820056FF9C /* opennurbs_uuid.cpp in Sources */, - A1C9656727FCBF7F006A1C3E /* opennurbs_current_environment.cpp in Sources */, 10D7D05909E04F820056FF9C /* opennurbs_viewport.cpp in Sources */, D6184CCD1B0F83800099E507 /* opennurbs_subd_copy.cpp in Sources */, 225F9B601E3FE9B900ED6334 /* opennurbs_internal_Vx_annotation.cpp in Sources */, @@ -2404,6 +2402,7 @@ DF6D389A1F2A72DF00D997E4 /* opennurbs_circle.cpp in Sources */, DF6D389B1F2A72DF00D997E4 /* opennurbs_parse_point.cpp in Sources */, DF6D389C1F2A72DF00D997E4 /* opennurbs_color.cpp in Sources */, + 997CC53528AEA8AB00E18BDB /* opennurbs_archivable_dictionary.cpp in Sources */, DF6D389D1F2A72DF00D997E4 /* opennurbs_cone.cpp in Sources */, DF6D389E1F2A72DF00D997E4 /* opennurbs_crc.cpp in Sources */, DF6D389F1F2A72DF00D997E4 /* opennurbs_mesh_topology.cpp in Sources */, @@ -2512,7 +2511,6 @@ DF6D38F81F2A72DF00D997E4 /* opennurbs_torus.cpp in Sources */, DF6D38F91F2A72DF00D997E4 /* opennurbs_userdata.cpp in Sources */, DF6D38FA1F2A72DF00D997E4 /* opennurbs_uuid.cpp in Sources */, - A1C9656827FCBF7F006A1C3E /* opennurbs_current_environment.cpp in Sources */, DF6D38FB1F2A72DF00D997E4 /* opennurbs_viewport.cpp in Sources */, DF6D38FC1F2A72DF00D997E4 /* opennurbs_subd_copy.cpp in Sources */, DF6D38FD1F2A72DF00D997E4 /* opennurbs_internal_Vx_annotation.cpp in Sources */, diff --git a/opennurbs_3dm_attributes.cpp b/opennurbs_3dm_attributes.cpp index 40a75f48..3892316c 100644 --- a/opennurbs_3dm_attributes.cpp +++ b/opennurbs_3dm_attributes.cpp @@ -12,6 +12,7 @@ //////////////////////////////////////////////////////////////// #include "opennurbs.h" +#include "opennurbs_internal_defines.h" #if !defined(ON_COMPILING_OPENNURBS) // This check is included in all opennurbs source .c and .cpp files to insure @@ -25,6 +26,7 @@ class ON_3dmObjectAttributesPrivate { public: ON_3dmObjectAttributesPrivate(); + bool operator==(const ON_3dmObjectAttributesPrivate&) const; bool operator!=(const ON_3dmObjectAttributesPrivate&) const; @@ -40,6 +42,9 @@ public: double m_linetype_scale = 1.0; ON_Color m_hatch_background_fill; bool m_hatch_boundary_visible = false; + + ON_DecalCollection m_decals; + ON_MeshModifiers m_mesh_modifiers; }; ON_3dmObjectAttributesPrivate::ON_3dmObjectAttributesPrivate() @@ -1649,66 +1654,66 @@ const ON_wString ON_3dmObjectAttributes::Name() const } -//unsigned int ON_3dmObjectAttributes::ApplyParentalControl( -// const ON_3dmObjectAttributes& parents_attributes, -// unsigned int control_limits -// ) -//{ -// ON_ERROR("Do not use deprecated version of ON_3dmObjectAttributes::ApplyParentalControl()"); -// ON_Layer bogus_layer; -// bogus_layer.m_layer_index = -1; -// return ApplyParentalControl(parents_attributes,bogus_layer,control_limits); -//} - unsigned int ON_3dmObjectAttributes::ApplyParentalControl( const ON_3dmObjectAttributes& parents_attributes, const ON_Layer& parent_layer, unsigned int control_limits ) +{ + unsigned int rc = ApplyParentalControl(parents_attributes, parent_layer, ON_nil_uuid, control_limits); + return rc; +} + +unsigned int ON_3dmObjectAttributes::ApplyParentalControl( + const ON_3dmObjectAttributes& parents_attributes, + const ON_Layer& parent_layer, + const ON_UUID& viewport_id, + unsigned int control_limits +) { unsigned int rc = 0; - if ( m_bVisible && !parents_attributes.m_bVisible ) + if (m_bVisible && !parents_attributes.m_bVisible) { - if ( 0 != (0x01 & control_limits) ) + if (0 != (0x01 & control_limits)) { rc |= 0x01; m_bVisible = false; } } - if ( ON::color_from_parent == m_color_source ) + if (ON::color_from_parent == m_color_source) { - if ( 0 != (0x02 & control_limits) ) + if (0 != (0x02 & control_limits)) { rc |= 0x02; m_color_source = parents_attributes.m_color_source; - m_color = parents_attributes.m_color; + m_color = parents_attributes.m_color; // 2010 March 10 Dale Lear // Changing the layer index is wrong! // Color by parent means COLOR and not LAYER // WRONG! // m_layer_index = parents_attributes.m_layer_index; - if ( ON::color_from_layer == m_color_source && parent_layer.Index() >= 0 ) + if (ON::color_from_layer == m_color_source && parent_layer.Index() >= 0) { // this object will use the parent layer's color m_color_source = ON::color_from_object; - m_color = parent_layer.m_color; + m_color = parent_layer.PerViewportColor(viewport_id); } } } - if ( ON::material_from_parent == m_material_source ) + if (ON::material_from_parent == m_material_source) { - if ( 0 != (0x04 & control_limits) ) + if (0 != (0x04 & control_limits)) { rc |= 0x04; m_material_source = parents_attributes.m_material_source; - m_material_index = parents_attributes.m_material_index; + m_material_index = parents_attributes.m_material_index; // 2010 March 10 Dale Lear // Changing the layer index is wrong! // Material by parent means MATERIAL and not LAYER // WRONG! // m_layer_index = parents_attributes.m_layer_index; - if ( ON::material_from_layer == m_material_source && parent_layer.Index() >= 0 ) + if (ON::material_from_layer == m_material_source && parent_layer.Index() >= 0) { // this object will use the parent layer's material m_material_source = ON::material_from_object; @@ -1717,63 +1722,124 @@ unsigned int ON_3dmObjectAttributes::ApplyParentalControl( } } - if ( ON::plot_color_from_parent == m_plot_color_source ) + if (ON::plot_color_from_parent == m_plot_color_source) { - if ( 0 != (0x08 & control_limits) ) + if (0 != (0x08 & control_limits)) { rc |= 0x08; m_plot_color_source = parents_attributes.m_plot_color_source; - m_plot_color = parents_attributes.m_plot_color; - if ( ON::plot_color_from_layer == m_plot_color_source && parent_layer.Index() >= 0 ) + m_plot_color = parents_attributes.m_plot_color; + if (ON::plot_color_from_layer == m_plot_color_source && parent_layer.Index() >= 0) { // this object will use the parent layer's plot color m_plot_color_source = ON::plot_color_from_object; - m_plot_color = parent_layer.m_plot_color; + m_plot_color = parent_layer.PerViewportPlotColor(viewport_id); } } } - if ( ON::plot_weight_from_parent == m_plot_weight_source ) + if (ON::plot_weight_from_parent == m_plot_weight_source) { - if ( 0 != (0x10 & control_limits) ) + if (0 != (0x10 & control_limits)) { rc |= 0x10; m_plot_weight_source = parents_attributes.m_plot_weight_source; - m_plot_weight_mm = parents_attributes.m_plot_weight_mm; - if ( ON::plot_weight_from_layer == m_plot_weight_source && parent_layer.Index() >= 0 ) + m_plot_weight_mm = parents_attributes.m_plot_weight_mm; + if (ON::plot_weight_from_layer == m_plot_weight_source && parent_layer.Index() >= 0) { // this object will use the parent layer's plot weight m_plot_weight_source = ON::plot_weight_from_object; - m_plot_weight_mm = parent_layer.m_plot_weight_mm; + m_plot_weight_mm = parent_layer.PerViewportPlotWeight(viewport_id); } } } - if ( ON::linetype_from_parent == m_linetype_source ) + if (ON::linetype_from_parent == m_linetype_source) { - if ( 0 != (0x20 & control_limits) ) + if (0 != (0x20 & control_limits)) { rc |= 0x20; m_linetype_source = parents_attributes.m_linetype_source; - m_linetype_index = parents_attributes.m_linetype_index; - if ( ON::linetype_from_layer == m_linetype_source && parent_layer.Index() >= 0 ) + m_linetype_index = parents_attributes.m_linetype_index; + if (ON::linetype_from_layer == m_linetype_source && parent_layer.Index() >= 0) { // this object will use the parent layer's line type m_linetype_source = ON::linetype_from_object; - m_linetype_index = parent_layer.m_linetype_index; + m_linetype_index = parent_layer.m_linetype_index; } } } - - if ( 0 != (0x40 & control_limits) ) + + if (0 != (0x40 & control_limits)) { rc |= 0x40; m_display_order = parents_attributes.m_display_order; } + if (ON::ClipParticipationSource::FromParent == ClipParticipationSource()) + { + if (0 != (0x80 & control_limits)) + { + rc |= 0x80; + SetClipParticipationSource(parents_attributes.ClipParticipationSource()); + if (ON::ClipParticipationSource::FromLayer == ClipParticipationSource() && parent_layer.Index() >= 0) + { + SetClipParticipationSource(ON::ClipParticipationSource::FromObject); + bool forAll = false; + bool forNone = false; + ON_UuidList list; + parent_layer.GetClipParticipation(forAll, forNone, list); + if (forAll) + SetClipParticipationForAll(); + else if (forNone) + SetClipParticipationForNone(); + else if (list.Count() > 0) + SetClipParticipationList(list.Array(), list.Count()); + } + if (ON::ClipParticipationSource::FromObject == ClipParticipationSource()) + { + bool forAll = false; + bool forNone = false; + ON_UuidList list; + parents_attributes.GetClipParticipation(forAll, forNone, list); + if (forAll) + SetClipParticipationForAll(); + else if (forNone) + SetClipParticipationForNone(); + else if (list.Count() > 0) + SetClipParticipationList(list.Array(), list.Count()); + } + } + } + + if (ON::SectionAttributesSource::FromParent == SectionAttributesSource()) + { + if (0 != (0x100 & control_limits)) + { + rc |= 0x100; + SetSectionAttributesSource(parents_attributes.SectionAttributesSource()); + if (ON::SectionAttributesSource::FromLayer == SectionAttributesSource() && parent_layer.Index() >= 0) + { + SetSectionAttributesSource(ON::SectionAttributesSource::FromLayer); + SetSectionFillRule(parent_layer.SectionFillRule()); + SetSectionHatchIndex(parent_layer.SectionHatchIndex()); + SetSectionHatchRotation(parent_layer.SectionHatchRotation()); + SetSectionHatchScale(parent_layer.SectionHatchScale()); + } + else + { + SetSectionFillRule(parents_attributes.SectionFillRule()); + SetSectionHatchIndex(parents_attributes.SectionHatchIndex()); + SetSectionHatchRotation(parents_attributes.SectionHatchRotation()); + SetSectionHatchScale(parents_attributes.SectionHatchScale()); + } + } + } + return rc; } + ON::object_color_source ON_3dmObjectAttributes::ColorSource() const { return ON::ObjectColorSource(m_color_source); @@ -2320,7 +2386,6 @@ void ON_3dmObjectAttributes::SetHatchBoundaryVisible(bool on) m_private->m_hatch_boundary_visible = on; } - //https://mcneel.myjetbrains.com/youtrack/issue/RH-20531 ON_Plane ON_3dmObjectAttributes::ObjectFrame(const ON_COMPONENT_INDEX&, bool bRaw) const { @@ -2354,11 +2419,45 @@ void ON_3dmObjectAttributes::SetObjectFrame(const ON_COMPONENT_INDEX& ci, const m_object_frame = plane; } +ON_Decal* ON_3dmObjectAttributes::AddDecal(void) +{ + if (nullptr == m_private) + m_private = new ON_3dmObjectAttributesPrivate; + + return m_private->m_decals.AddDecal(); +} + +ON_MeshModifiers& ON_3dmObjectAttributes::MeshModifiers(void) const +{ + if (nullptr == m_private) + m_private = new ON_3dmObjectAttributesPrivate; + + return m_private->m_mesh_modifiers; +} + +void ON_3dmObjectAttributes::Internal_PopulateDecals(const ON_XMLRootNode& node) const +{ + if (!ON_DecalCollection::NodeContainsDecals(node)) + return; + + if (nullptr == m_private) + m_private = new ON_3dmObjectAttributesPrivate; + + m_private->m_decals.Populate(node); +} + +const ON_SimpleArray& ON_3dmObjectAttributes::GetDecalArray(void) const +{ + if (nullptr == m_private) + m_private = new ON_3dmObjectAttributesPrivate; + + return m_private->m_decals.GetDecalArray(); +} + // {1403A7E4-E7AD-4a01-A2AA-41DAE6BE7ECB} const ON_UUID ON_DisplayMaterialRef::m_invisible_in_detail_id = { 0x1403a7e4, 0xe7ad, 0x4a01, { 0xa2, 0xaa, 0x41, 0xda, 0xe6, 0xbe, 0x7e, 0xcb } }; - ON_DisplayMaterialRef::ON_DisplayMaterialRef() { m_viewport_id = ON_nil_uuid; @@ -2402,6 +2501,3 @@ bool ON_DisplayMaterialRef::operator>=(const ON_DisplayMaterialRef& other) const { return (Compare(other)>=0); } - - - diff --git a/opennurbs_3dm_attributes.h b/opennurbs_3dm_attributes.h index da74a336..f84941dc 100644 --- a/opennurbs_3dm_attributes.h +++ b/opennurbs_3dm_attributes.h @@ -148,10 +148,10 @@ public: 2: color 4: render material 8: plot color - 0x10: plot weight - 0x20: linetype - 0x40: display order - + 0x10: plot weight + 0x20: linetype + 0x40: display order + 0x80: clip participation Returns: The bits in the returned integer indicate which attributes were actually modified. @@ -160,9 +160,11 @@ public: 2: color 4: render material 8: plot color - 0x10: plot weight - 0x20: linetype - 0x40: display order + 0x10: plot weight + 0x20: linetype + 0x40: display order + 0x80: clip participation + 0x100: section style */ unsigned int ApplyParentalControl( const ON_3dmObjectAttributes& parent_attributes, @@ -170,6 +172,13 @@ public: unsigned int control_limits = 0xFFFFFFFF ); + unsigned int ApplyParentalControl( + const ON_3dmObjectAttributes& parent_attributes, + const ON_Layer& parent_layer, + const ON_UUID& viewport_id, + unsigned int control_limits = 0xFFFFFFFF + ); + // Every OpenNURBS object has a UUID (universally unique identifier). When // an OpenNURBS object is added to a model, the value is checked. If the // value is ON_nil_uuid, a new UUID is created. If the value is not @@ -497,14 +506,35 @@ public: int // zero based group index ); - // removes the object from the last group in the group list + // Removes the object from the last group in the group list. void RemoveFromTopGroup(); // Removes object from all groups. void RemoveFromAllGroups(); + // Decals. - // display material references + /* + Description: + Get an array of decals that are stored on this attributes object. + */ + const ON_SimpleArray& GetDecalArray(void) const; + + /* + Description: + Add a new decal to this attributes object. + */ + ON_Decal* AddDecal(void); + + // Mesh Modifiers. + + /* + Description: + Get the mesh modifiers that are stored on this attributes object. + */ + class ON_MeshModifiers& MeshModifiers(void) const; + + // Display material references. /* Description: @@ -614,13 +644,13 @@ public: /* Description: - Remove a the entire display material reference list. + Remove the entire display material reference list. */ void RemoveAllDisplayMaterialRefs(); /* Returns: - Number of diplay material refences. + Number of display material references. */ int DisplayMaterialRefCount() const; @@ -629,6 +659,9 @@ public: private: bool Internal_WriteV5( ON_BinaryArchive& archive ) const; bool Internal_ReadV5( ON_BinaryArchive& archive ); + +public: + void Internal_PopulateDecals(const ON_XMLRootNode&) const; }; #endif diff --git a/opennurbs_3dm_properties.h b/opennurbs_3dm_properties.h index e1305bf7..82c7f75d 100644 --- a/opennurbs_3dm_properties.h +++ b/opennurbs_3dm_properties.h @@ -143,7 +143,7 @@ class ON_CLASS ON_3dmProperties { public: ON_3dmProperties() = default; - ~ON_3dmProperties() = default;; + ~ON_3dmProperties() = default; ON_3dmProperties(const ON_3dmProperties&) = default; ON_3dmProperties& operator=(const ON_3dmProperties&) = default; diff --git a/opennurbs_archivable_dictionary.cpp b/opennurbs_archivable_dictionary.cpp new file mode 100644 index 00000000..567f02a2 --- /dev/null +++ b/opennurbs_archivable_dictionary.cpp @@ -0,0 +1,1346 @@ +#include "opennurbs.h" +#include +#include + +#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. +// When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined +// and the opennurbs .h files alter what is declared and how it is declared. +#error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs +#endif + +//////////////////////////////////////////////////////////////////////////////// + +enum class DictionaryEntryType : int +{ + // values <= 0 are considered bogus + // each supported object type has an associated DictionaryEntryType enum value + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // NEVER EVER Change DictionaryEntryType values as this will break I/O code + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + Undefined = 0, + + // some basic data types + Boolean = 1, // bool + UInt8 = 2, // uint8_t + Int8 = 3, // int8_t + Int16 = 4, // int16_t + UInt16 = 5, // uint16_t + Int32 = 6, // int32_t + UInt32 = 7, // uint32_t + Int64 = 8, // int64_t + Float = 9, // float + Double = 10, // double + Uuid = 11, + String = 12, + + // array of basic data types + BooleanArray = 13, + UInt8Array = 14, + Int8Array = 15, + Int16Array = 16, + Int32Array = 17, + FloatArray = 18, + DoubleArray = 19, + UuidArray = 20, + StringArray = 21, + + Color = 22, + Point2i = 23, + Point2f = 24, + Rect4i = 25, + Rect4f = 26, + Size2i = 27, + Size2f = 28, + Font = 29, + + Interval = 30, + Point2d = 31, + Point3d = 32, + Point4d = 33, + Vector2d = 34, + Vector3d = 35, + BoundingBox = 36, + Ray3d = 37, + PlaneEquation = 38, + Xform = 39, + Plane = 40, + Line = 41, + Point3f = 42, + Vector3f = 43, + + ArchivableDictionary = 44, + Object = 45, // OBSOLETE + MeshParameters = 46, + Geometry = 47, +}; + +//////////////////////////////////////////////////////////////////////////////// + +class DictionaryEntry +{ +public: + static DictionaryEntry* CreateInstance(enum DictionaryEntryType item_type); + virtual ~DictionaryEntry() = default; + + virtual enum DictionaryEntryType EntryType() const = 0; + virtual DictionaryEntry* Duplicate() const = 0; + + virtual bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const = 0; + virtual bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) = 0; +}; + +template +class DictionaryEntryT : public DictionaryEntry +{ +protected: + using value_type = V; + using reference = V&; + using const_reference = const V&; + + value_type m_value; + +public: + enum DictionaryEntryType EntryType() const override { return T; } + static const DictionaryEntryType Type = T; + + DictionaryEntryT() : m_value() { } + DictionaryEntryT(const_reference value) : m_value(value) { } + virtual ~DictionaryEntryT() override = default; + + const_reference Value() const { return m_value; } + reference Value() { return m_value; } +}; + +template +class Entry; + +template +static std::unique_ptr> make_entry(const T& value) +{ + return std::make_unique>(value); +} + +template +static std::unique_ptr::type>>> make_entry(const std::shared_ptr& value) +{ + return std::make_unique::type>>> + (std::make_shared::type>(*value)); +} + +//////////////////////////////////////////////////////////////////////////////// +class ON_ArchivableDictionaryPrivate +{ +public: + ON_ArchivableDictionaryPrivate() = default; + ~ON_ArchivableDictionaryPrivate() = default; + + ON_ArchivableDictionaryPrivate(const ON_ArchivableDictionaryPrivate& other) : + m_version(other.m_version), + m_name(other.m_name) + { + for (const auto & item : other.m_map) + { + const auto& key = item.first; + const auto& value = item.second; + m_map[key].reset(value->Duplicate()); + } + } + + ON_ArchivableDictionaryPrivate& operator=(const ON_ArchivableDictionaryPrivate& other) + { + m_version = other.m_version; + m_name = other.m_name; + + m_map.clear(); + for (const auto & item : other.m_map) + { + const auto& key = item.first; + const auto& value = item.second; + m_map[key].reset(value->Duplicate()); + } + + return *this; + } + + unsigned int m_version = 0; + ON_wString m_name = ON_wString::EmptyString; + + // std::less is important to enable ON_wString-wchar_t* comparsion without an implicit copy. + std::map, std::less> m_map; + + template + bool TrySetValue(const wchar_t* key, const V& value) + { + auto r = m_map.insert({ key, nullptr }); + auto& entry_ptr = r.first->second; + + if (r.second) + { + entry_ptr = make_entry(value); + return true; + } + else if (entry_ptr->EntryType() == Entry::Type) + { + static_cast*>(entry_ptr.get())->Value() = value; + return true; + } + + return false; + } + + template + bool TryGetValue(const wchar_t* key, T& value) const + { + const auto iterator = m_map.find(key); + if (iterator == m_map.end()) return false; + + const auto entry = iterator->second.get(); + if (entry->EntryType() != Entry::Type) + return false; + + value = static_cast*>(entry)->Value(); + return true; + } + + template + const T& SetValue(const wchar_t* key, const T& value) + { + auto r = m_map.insert({ key, nullptr }); + auto& entry_ptr = r.first->second; + + if (!r.second && entry_ptr->EntryType() == Entry::Type) + { + return static_cast*>(entry_ptr.get())->Value() = value; + } + else + { + entry_ptr = make_entry(value); + return static_cast*>(entry_ptr.get())->Value(); + } + } + + template + const std::shared_ptr::type>& SetValue(const wchar_t* key, const std::shared_ptr& value) + { + auto entry = (m_map[key] = make_entry(value)).get(); + return static_cast::type>>*>(entry)->Value(); + } + + template + T GetValue(const wchar_t* key) const + { + T value{}; + TryGetValue(key, value); + return value; + } +}; + +typedef std::shared_ptr ON_ArchivableDictionaryPtr; + +//////////////////////////////////////////////////////////////////////////////// +// Empty +//////////////////////////////////////////////////////////////////////////////// + +const ON_ArchivableDictionary ON_ArchivableDictionary::Empty; + +//////////////////////////////////////////////////////////////////////////////// +// Default +//////////////////////////////////////////////////////////////////////////////// + +ON_ArchivableDictionary::ON_ArchivableDictionary() : + m_private(new ON_ArchivableDictionaryPrivate) +{ +} + +ON_ArchivableDictionary::~ON_ArchivableDictionary() +{ + delete m_private; +} + +//////////////////////////////////////////////////////////////////////////////// +// Copy +//////////////////////////////////////////////////////////////////////////////// + +ON_ArchivableDictionary::ON_ArchivableDictionary(const ON_ArchivableDictionary& src) : + m_private(new ON_ArchivableDictionaryPrivate(*src.m_private)) +{ +} + +ON_ArchivableDictionary& ON_ArchivableDictionary::operator=(const ON_ArchivableDictionary& src) +{ + *m_private = *src.m_private; + return *this; +} + +#if defined(ON_HAS_RVALUEREF) +//////////////////////////////////////////////////////////////////////////////// +// Move +//////////////////////////////////////////////////////////////////////////////// + +ON_ArchivableDictionary::ON_ArchivableDictionary(ON_ArchivableDictionary&& src) ON_NOEXCEPT + : m_private(src.m_private) +{ + src.m_private = nullptr; +} + +ON_ArchivableDictionary& ON_ArchivableDictionary::operator=(ON_ArchivableDictionary&& src) ON_NOEXCEPT +{ + delete m_private; + m_private = src.m_private; + src.m_private = nullptr; + + return *this; +} +#endif + +//////////////////////////////////////////////////////////////////////////////// + +static const ON_UUID RhinoDotNetDictionaryId = ON_UuidFromString("21EE7933-1E2D-4047-869E-6BDBF986EA11"); + +bool ON_ArchivableDictionary::Write(ON_BinaryArchive& binary_archive) const +{ + if (!binary_archive.BeginWriteDictionary(RhinoDotNetDictionaryId, m_private->m_version, m_private->m_name)) + return false; + + for (const auto& item : m_private->m_map) + { + const auto& key = item.first; + const auto& value = item.second; + + if (!binary_archive.BeginWriteDictionaryEntry((int) value->EntryType(), key)) + return false; + + if (!value->WriteDictionaryEntry(binary_archive)) + return false; + + if (!binary_archive.EndWriteDictionaryEntry()) + return false; + } + + return binary_archive.EndWriteDictionary(); +} + +bool ON_ArchivableDictionary::Read(ON_BinaryArchive& binary_archive) +{ + ON_UUID dictionary_id = {}; + unsigned int dictionary_version = {}; + ON_wString dictionary_name; + m_private->m_map.clear(); + + if (!binary_archive.BeginReadDictionary(&dictionary_id, &dictionary_version, dictionary_name)) + return false; + + if (dictionary_id != RhinoDotNetDictionaryId) + return false; + + while (true) + { + int item_type; + ON_wString item_name; + auto rc = binary_archive.BeginReadDictionaryEntry(&item_type, item_name); + if (rc == 1) + { + auto value = DictionaryEntry::CreateInstance((DictionaryEntryType) item_type); + if (value != nullptr) + { + if (!value->ReadDictionaryEntry(binary_archive)) + return false; + + m_private->m_map[item_name].reset(value); + } + } + else if (rc == 2) break; + else return false; + + if (!binary_archive.EndReadDictionaryEntry()) + return false; + } + + return binary_archive.EndReadDictionary(); +} + +//////////////////////////////////////////////////////////////////////////////// + +int ON_ArchivableDictionary::Count() const +{ + return (int)m_private->m_map.size(); +} + +void ON_ArchivableDictionary::Clear() +{ + m_private->m_map.clear(); +} + +ON_ClassArray ON_ArchivableDictionary::GetKeys() const +{ + ON_ClassArray keys(Count()); + + for (const auto & entry : m_private->m_map) + keys.Append(entry.first); + + return keys; +} + +bool ON_ArchivableDictionary::ContainsKey(const wchar_t* key) const +{ + return m_private->m_map.find(key) != m_private->m_map.cend(); +} + +bool ON_ArchivableDictionary::Remove(const wchar_t* key) +{ + const auto iterator = m_private->m_map.find(key); + if (iterator == m_private->m_map.end()) + return false; + + m_private->m_map.erase(iterator); + return true; +} + +bool ON_ArchivableDictionary::CopyValue(const wchar_t* key, const ON_ArchivableDictionary& source, const wchar_t* source_key) +{ + if (source_key == nullptr) + source_key = key; + + const auto iterator = source.m_private->m_map.find(source_key); + if (iterator != source.m_private->m_map.end()) + { + m_private->m_map[key].reset(iterator->second->Duplicate()); + return true; + } + + return false; +} + +void ON_ArchivableDictionary::CopyValues(const ON_ArchivableDictionary& source) +{ + if (this != &source) + { + for (const auto& entry : source.m_private->m_map) + m_private->m_map[entry.first].reset(entry.second->Duplicate()); + } +} + +#pragma region Getters-Setters Primitives + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteBool(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadBool(&m_value); } +}; + +bool ON_ArchivableDictionary::TrySetBool(const wchar_t* key, bool value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetBool(const wchar_t* key, bool& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetBool(const wchar_t* key, bool value) +{ + m_private->SetValue(key, value); +} + +bool ON_ArchivableDictionary::GetBool(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteByte(1, &m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadByte(1, &m_value); } +}; + +bool ON_ArchivableDictionary::TrySetUInt8(const wchar_t* key, ON__UINT8 value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetUInt8(const wchar_t* key, ON__UINT8& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetUInt8(const wchar_t* key, ON__UINT8 value) +{ + m_private->SetValue(key, value); +} + +ON__UINT8 ON_ArchivableDictionary::GetUInt8(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteByte(1, &m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadByte(1, &m_value); } +}; + +bool ON_ArchivableDictionary::TrySetInt8(const wchar_t* key, ON__INT8 value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetInt8(const wchar_t* key, ON__INT8& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetInt8(const wchar_t* key, ON__INT8 value) +{ + m_private->SetValue(key, value); +} + +ON__INT8 ON_ArchivableDictionary::GetInt8(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteShort(1, &m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadShort(1, &m_value); } +}; + +bool ON_ArchivableDictionary::TrySetInt16(const wchar_t* key, ON__INT16 value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetInt16(const wchar_t* key, ON__INT16& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetInt16(const wchar_t* key, ON__INT16 value) +{ + m_private->SetValue(key, value); +} + +ON__INT16 ON_ArchivableDictionary::GetInt16(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteShort(1, &m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadShort(1, &m_value); } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteInt(1, &m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadInt(1, &m_value); } +}; + +bool ON_ArchivableDictionary::TrySetInt32(const wchar_t* key, ON__INT32 value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetInt32(const wchar_t* key, ON__INT32& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetInt32(const wchar_t* key, ON__INT32 value) +{ + m_private->SetValue(key, value); +} + +ON__INT32 ON_ArchivableDictionary::GetInt32(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteInt(1, &m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadInt(1, &m_value); } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteBigInt(1, &m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadBigInt(1, &m_value); } +}; + +bool ON_ArchivableDictionary::TrySetInt64(const wchar_t* key, ON__INT64 value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetInt64(const wchar_t* key, ON__INT64& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetInt64(const wchar_t* key, ON__INT64 value) +{ + m_private->SetValue(key, value); +} + +ON__INT64 ON_ArchivableDictionary::GetInt64(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteFloat(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadFloat(&m_value); } +}; + +bool ON_ArchivableDictionary::TrySetFloat(const wchar_t* key, float value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetFloat(const wchar_t* key, float& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetFloat(const wchar_t* key, float value) +{ + m_private->SetValue(key, value); +} + +float ON_ArchivableDictionary::GetFloat(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteDouble(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadDouble(&m_value); } +}; + +bool ON_ArchivableDictionary::TrySetDouble(const wchar_t* key, double value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetDouble(const wchar_t* key, double& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetDouble(const wchar_t* key, double value) +{ + m_private->SetValue(key, value); +} + +double ON_ArchivableDictionary::GetDouble(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteUuid(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadUuid(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetUuid(const wchar_t* key, ON_UUID value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetUuid(const wchar_t* key, ON_UUID& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetUuid(const wchar_t* key, ON_UUID value) +{ + m_private->SetValue(key, value); +} + +ON_UUID ON_ArchivableDictionary::GetUuid(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteString(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadString(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetString(const wchar_t* key, const ON_wString& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetString(const wchar_t* key, ON_wString& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetString(const wchar_t* key, const ON_wString& value) +{ + m_private->SetValue(key, value); +} + +ON_wString ON_ArchivableDictionary::GetString(const wchar_t* key) const +{ + return m_private->GetValue(key); +} + +#pragma endregion + +//////////////////////////////////////////////////////////////////////////////// + +#pragma region Getters-Setters Primitive Arrays + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::BooleanArray> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetBoolArray(const wchar_t* key, const ON_SimpleArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetBoolArray(const wchar_t* key, ON_SimpleArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetBoolArray(const wchar_t* key, const ON_SimpleArray& value) +{ + m_private->SetValue(key, value); +} + +ON_SimpleArray ON_ArchivableDictionary::GetBoolArray(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::UInt8Array> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetUInt8Array(const wchar_t* key, const ON_SimpleArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetUInt8Array(const wchar_t* key, ON_SimpleArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetUInt8Array(const wchar_t* key, const ON_SimpleArray& value) +{ + m_private->SetValue(key, value); +} + +ON_SimpleArray ON_ArchivableDictionary::GetUInt8Array(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::Int8Array> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetInt8Array(const wchar_t* key, const ON_SimpleArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetInt8Array(const wchar_t* key, ON_SimpleArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetInt8Array(const wchar_t* key, const ON_SimpleArray& value) +{ + m_private->SetValue(key, value); +} + +ON_SimpleArray ON_ArchivableDictionary::GetInt8Array(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::Int16Array> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetInt16Array(const wchar_t* key, const ON_SimpleArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetInt16Array(const wchar_t* key, ON_SimpleArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetInt16Array(const wchar_t* key, const ON_SimpleArray& value) +{ + m_private->SetValue(key, value); +} + +ON_SimpleArray ON_ArchivableDictionary::GetInt16Array(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::Int32Array> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetInt32Array(const wchar_t* key, const ON_SimpleArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetInt32Array(const wchar_t* key, ON_SimpleArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetInt32Array(const wchar_t* key, const ON_SimpleArray& value) +{ + m_private->SetValue(key, value); +} + +ON_SimpleArray ON_ArchivableDictionary::GetInt32Array(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::FloatArray> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetFloatArray(const wchar_t* key, const ON_SimpleArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetFloatArray(const wchar_t* key, ON_SimpleArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetFloatArray(const wchar_t* key, const ON_SimpleArray& value) +{ + m_private->SetValue(key, value); +} + +ON_SimpleArray ON_ArchivableDictionary::GetFloatArray(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::DoubleArray> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetDoubleArray(const wchar_t* key, const ON_SimpleArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetDoubleArray(const wchar_t* key, ON_SimpleArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetDoubleArray(const wchar_t* key, const ON_SimpleArray& value) +{ + m_private->SetValue(key, value); +} + +ON_SimpleArray ON_ArchivableDictionary::GetDoubleArray(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::UuidArray> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetUuidArray(const wchar_t* key, const ON_SimpleArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetUuidArray(const wchar_t* key, ON_SimpleArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetUuidArray(const wchar_t* key, const ON_SimpleArray& value) +{ + m_private->SetValue(key, value); +} + +ON_SimpleArray ON_ArchivableDictionary::GetUuidArray(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry> : public DictionaryEntryT, DictionaryEntryType::StringArray> +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteArray(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadArray(m_value); } +}; + +bool ON_ArchivableDictionary::TrySetStringArray(const wchar_t* key, const ON_ClassArray& value) +{ + return m_private->TrySetValue(key, value); +} + +bool ON_ArchivableDictionary::TryGetStringArray(const wchar_t* key, ON_ClassArray& value) const +{ + return m_private->TryGetValue(key, value); +} + +void ON_ArchivableDictionary::SetStringArray(const wchar_t* key, const ON_ClassArray& value) +{ + m_private->SetValue(key, value); +} + +ON_ClassArray ON_ArchivableDictionary::GetStringArray(const wchar_t* key) const +{ + return m_private->GetValue>(key); +} + +#pragma endregion + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteColor(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadColor(m_value); } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const + { + return binary_archive.WriteInt(m_value.x) && binary_archive.WriteInt(m_value.y); + } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) + { + return binary_archive.ReadInt(&m_value.x) && binary_archive.ReadInt(&m_value.y); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const + { + return binary_archive.WriteFloat(m_value.x) && binary_archive.WriteFloat(m_value.y); + } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) + { + return binary_archive.ReadFloat(&m_value.x) && binary_archive.ReadFloat(&m_value.y); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const + { + const int values[]{ m_value.left, m_value.top, m_value.right - m_value.left, m_value.bottom - m_value.top }; + return binary_archive.WriteInt(4, values); + } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) + { + int values[]{ 0, 0, 0, 0 }; + if (!binary_archive.ReadInt(4, values)) + return false; + + m_value.SetRect(values[0], values[1], values[0] + values[2], values[1] + values[3]); + return true; + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteInt(m_value.cx) && binary_archive.WriteInt(m_value.cy); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadInt(&m_value.cx) && binary_archive.ReadInt(&m_value.cy); } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WritePoint(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadPoint(m_value); } +}; + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WritePoint(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadPoint(m_value); } +}; + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WritePoint(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadPoint(m_value); } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteVector(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadVector(m_value); } +}; + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return binary_archive.WriteVector(m_value); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return binary_archive.ReadVector(m_value); } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return m_value->Write(binary_archive); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return m_value->Read(binary_archive); } +}; + +//////////////////////////////////////////////////////////////////////////////// +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return m_value.Write(binary_archive); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return m_value.Read(binary_archive); } +}; + +//////////////////////////////////////////////////////////////////////////////// +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return m_value.Write(binary_archive); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return m_value.Read(binary_archive); } +}; + +//////////////////////////////////////////////////////////////////////////////// +template <> class Entry : public DictionaryEntryT +{ +public: + Entry() = default; + Entry(const value_type& value) : DictionaryEntryT(value) {} + virtual DictionaryEntry* Duplicate() const { return new Entry(m_value); } + + bool WriteDictionaryEntry(ON_BinaryArchive& binary_archive) const { return m_value.Write(binary_archive); } + bool ReadDictionaryEntry(ON_BinaryArchive& binary_archive) { return m_value.Read(binary_archive); } +}; + +//////////////////////////////////////////////////////////////////////////////// +DictionaryEntry* DictionaryEntry::CreateInstance(enum DictionaryEntryType item_type) +{ + switch (item_type) + { + // some basic data types + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + + // array of basic data types + case Entry>::Type: return new Entry>; + case Entry>::Type: return new Entry>; + case Entry>::Type: return new Entry>; + case Entry>::Type: return new Entry>; + case Entry>::Type: return new Entry>; + case Entry>::Type: return new Entry>; + case Entry>::Type: return new Entry>; + case Entry>::Type: return new Entry>; + case Entry>::Type: return new Entry>; + + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + + //case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + //case Entry::Type: return new Entry; + + case DictionaryEntryType::Object: return new Entry; + case DictionaryEntryType::MeshParameters: return new Entry; + case DictionaryEntryType::Geometry: return new Entry; + case DictionaryEntryType::ArchivableDictionary: return new Entry; + } + + return nullptr; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/opennurbs_archivable_dictionary.h b/opennurbs_archivable_dictionary.h new file mode 100644 index 00000000..9c4185e7 --- /dev/null +++ b/opennurbs_archivable_dictionary.h @@ -0,0 +1,155 @@ +// +// Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved. +// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert +// McNeel & Associates. +// +// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. +// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF +// MERCHANTABILITY ARE HEREBY DISCLAIMED. +// +// For complete openNURBS copyright information see . +// +//////////////////////////////////////////////////////////////// + +#if !defined(OPENNURBS_ARCHIVABLE_DICTIONARY_INC_) +#define OPENNURBS_ARCHIVABLE_DICTIONARY_INC_ + +class ON_CLASS ON_ArchivableDictionary +{ +public: + static const ON_ArchivableDictionary Empty; + + ON_ArchivableDictionary(); + virtual ~ON_ArchivableDictionary(); + + ON_ArchivableDictionary(const ON_ArchivableDictionary& src); + ON_ArchivableDictionary& operator=(const ON_ArchivableDictionary& src); + +#if defined(ON_HAS_RVALUEREF) + ON_ArchivableDictionary(ON_ArchivableDictionary&& src) ON_NOEXCEPT; + ON_ArchivableDictionary& operator=(ON_ArchivableDictionary&& src) ON_NOEXCEPT; +#endif + + virtual bool Write(ON_BinaryArchive& binary_archive) const; + virtual bool Read(ON_BinaryArchive& binary_archive); + + int Count() const; // Number of elements in dictionary. + void Clear(); // Sets count to 0. + + ON_ClassArray GetKeys() const; + bool ContainsKey(const wchar_t* key) const; + bool Remove(const wchar_t* key); + + bool CopyValue(const wchar_t* key, const ON_ArchivableDictionary& source, const wchar_t* source_key = nullptr); + void CopyValues(const ON_ArchivableDictionary& source); + +#pragma region Getters-Setters Primitives + + bool TrySetBool(const wchar_t* key, bool value); + bool TryGetBool(const wchar_t* key, bool& value) const; + void SetBool(const wchar_t* key, bool value); + bool GetBool(const wchar_t* key) const; + + bool TrySetUInt8(const wchar_t* key, ON__UINT8 value); + bool TryGetUInt8(const wchar_t* key, ON__UINT8& value) const; + void SetUInt8(const wchar_t* key, ON__UINT8 value); + ON__UINT8 GetUInt8(const wchar_t* key) const; + + bool TrySetInt8(const wchar_t* key, ON__INT8 value); + bool TryGetInt8(const wchar_t* key, ON__INT8& value) const; + void SetInt8(const wchar_t* key, ON__INT8 value); + ON__INT8 GetInt8(const wchar_t* key) const; + + bool TrySetInt16(const wchar_t* key, ON__INT16 value); + bool TryGetInt16(const wchar_t* key, ON__INT16& value) const; + void SetInt16(const wchar_t* key, ON__INT16 value); + ON__INT16 GetInt16(const wchar_t* key) const; + + bool TrySetInt32(const wchar_t* key, ON__INT32 value); + bool TryGetInt32(const wchar_t* key, ON__INT32& value) const; + void SetInt32(const wchar_t* key, ON__INT32 value); + ON__INT32 GetInt32(const wchar_t* key) const; + + bool TrySetInt64(const wchar_t* key, ON__INT64 value); + bool TryGetInt64(const wchar_t* key, ON__INT64& value) const; + void SetInt64(const wchar_t* key, ON__INT64 value); + ON__INT64 GetInt64(const wchar_t* key) const; + + bool TrySetFloat(const wchar_t* key, float value); + bool TryGetFloat(const wchar_t* key, float& value) const; + void SetFloat(const wchar_t* key, float value); + float GetFloat(const wchar_t* key) const; + + bool TrySetDouble(const wchar_t* key, double value); + bool TryGetDouble(const wchar_t* key, double& value) const; + void SetDouble(const wchar_t* key, double value); + double GetDouble(const wchar_t* key) const; + + bool TrySetUuid(const wchar_t* key, ON_UUID value); + bool TryGetUuid(const wchar_t* key, ON_UUID& value) const; + void SetUuid(const wchar_t* key, ON_UUID value); + ON_UUID GetUuid(const wchar_t* key) const; + + bool TrySetString(const wchar_t* key, const ON_wString& value); + bool TryGetString(const wchar_t* key, ON_wString& value) const; + void SetString(const wchar_t* key, const ON_wString& value); + ON_wString GetString(const wchar_t* key) const; + +#pragma endregion + +#pragma region Getters-Setters Primitive Arrays + + bool TrySetBoolArray(const wchar_t* key, const ON_SimpleArray& value); + bool TryGetBoolArray(const wchar_t* key, ON_SimpleArray& value) const; + void SetBoolArray(const wchar_t* key, const ON_SimpleArray& value); + ON_SimpleArray GetBoolArray(const wchar_t* key) const; + + bool TrySetUInt8Array(const wchar_t* key, const ON_SimpleArray& value); + bool TryGetUInt8Array(const wchar_t* key, ON_SimpleArray& value) const; + void SetUInt8Array(const wchar_t* key, const ON_SimpleArray& value); + ON_SimpleArray GetUInt8Array(const wchar_t* key) const; + + bool TrySetInt8Array(const wchar_t* key, const ON_SimpleArray& value); + bool TryGetInt8Array(const wchar_t* key, ON_SimpleArray& value) const; + void SetInt8Array(const wchar_t* key, const ON_SimpleArray& value); + ON_SimpleArray GetInt8Array(const wchar_t* key) const; + + bool TrySetInt16Array(const wchar_t* key, const ON_SimpleArray& value); + bool TryGetInt16Array(const wchar_t* key, ON_SimpleArray& value) const; + void SetInt16Array(const wchar_t* key, const ON_SimpleArray& value); + ON_SimpleArray GetInt16Array(const wchar_t* key) const; + + bool TrySetInt32Array(const wchar_t* key, const ON_SimpleArray& value); + bool TryGetInt32Array(const wchar_t* key, ON_SimpleArray& value) const; + void SetInt32Array(const wchar_t* key, const ON_SimpleArray& value); + ON_SimpleArray GetInt32Array(const wchar_t* key) const; + + bool TrySetFloatArray(const wchar_t* key, const ON_SimpleArray& value); + bool TryGetFloatArray(const wchar_t* key, ON_SimpleArray& value) const; + void SetFloatArray(const wchar_t* key, const ON_SimpleArray& value); + ON_SimpleArray GetFloatArray(const wchar_t* key) const; + + bool TrySetDoubleArray(const wchar_t* key, const ON_SimpleArray& value); + bool TryGetDoubleArray(const wchar_t* key, ON_SimpleArray& value) const; + void SetDoubleArray(const wchar_t* key, const ON_SimpleArray& value); + ON_SimpleArray GetDoubleArray(const wchar_t* key) const; + + bool TrySetUuidArray(const wchar_t* key, const ON_SimpleArray& value); + bool TryGetUuidArray(const wchar_t* key, ON_SimpleArray& value) const; + void SetUuidArray(const wchar_t* key, const ON_SimpleArray& value); + ON_SimpleArray GetUuidArray(const wchar_t* key) const; + + bool TrySetStringArray(const wchar_t* key, const ON_ClassArray& value); + bool TryGetStringArray(const wchar_t* key, ON_ClassArray& value) const; + void SetStringArray(const wchar_t* key, const ON_ClassArray& value); + ON_ClassArray GetStringArray(const wchar_t* key) const; + +#pragma endregion +private: + class ON_ArchivableDictionaryPrivate* m_private = nullptr; + ON__UINT_PTR m_reserved = 0; +}; + +//////////////////////////////////////////////////////////////// + +#endif diff --git a/opennurbs_archive.cpp b/opennurbs_archive.cpp index 7f8724cb..dbee7dae 100644 --- a/opennurbs_archive.cpp +++ b/opennurbs_archive.cpp @@ -838,12 +838,27 @@ bool ON_BinaryArchive::Internal_SeekCur( bool bForward, ON__UINT64 offset ) return true; } - - bool ON_BinaryArchive::ReadChar( // Read an array of 8 bit chars + size_t count, // number of chars to read + char* p +) +{ + return ReadByte(count, p); +} + +bool +ON_BinaryArchive::ReadChar( // Read a single 8 bit char + char* p +) +{ + return ReadByte(1, p); +} + +bool +ON_BinaryArchive::ReadChar( // Read an array of 8 bit signed chars size_t count, // number of chars to read - char* p + ON__INT8* p ) { return ReadByte( count, p ); @@ -852,15 +867,15 @@ ON_BinaryArchive::ReadChar( // Read an array of 8 bit chars bool ON_BinaryArchive::ReadChar( // Read an array of 8 bit unsigned chars size_t count, // number of unsigned chars to read - unsigned char* p + ON__UINT8* p ) { return ReadByte( count, p ); } bool -ON_BinaryArchive::ReadChar( // Read a single 8 bit char - char* p +ON_BinaryArchive::ReadChar( // Read a single 8 bit signed char + ON__INT8* p ) { return ReadByte( 1, p ); @@ -868,7 +883,7 @@ ON_BinaryArchive::ReadChar( // Read a single 8 bit char bool ON_BinaryArchive::ReadChar( // Read a single 8 bit unsigned char - unsigned char* p + ON__UINT8* p ) { return ReadByte( 1, p ); @@ -896,8 +911,8 @@ ON_BinaryArchive::ReadInt16( // Read an array of 16 bit integers bool ON_BinaryArchive::ReadShort( // Read an array of 16 bit shorts - size_t count, // number of unsigned chars to read - short* p + size_t count, // number of signed chars to read + ON__INT16* p ) { #pragma ON_PRAGMA_WARNING_PUSH @@ -930,15 +945,15 @@ ON_BinaryArchive::ReadShort( // Read an array of 16 bit shorts bool ON_BinaryArchive::ReadShort( // Read an array of 16 bit unsigned shorts size_t count, // number of unsigned chars to read - unsigned short* p + ON__UINT16* p ) { return ReadShort( count, (short*)p ); } bool -ON_BinaryArchive::ReadShort( // Read a single 16 bit short - short* p +ON_BinaryArchive::ReadShort( // Read a single 16 bit signed short + ON__INT16* p ) { return ReadShort( 1, p ); @@ -946,15 +961,15 @@ ON_BinaryArchive::ReadShort( // Read a single 16 bit short bool ON_BinaryArchive::ReadShort( // Read a single 16 bit unsigned short - unsigned short* p + ON__UINT16* p ) { return ReadShort( 1, p ); } bool -ON_BinaryArchive::ReadInt32( // Read an array of 32 bit integers - size_t count, // number of 32 bit integers to read +ON_BinaryArchive::ReadInt32( // Read an array of 32 bit signed integers + size_t count, // number of 32 bit signed integers to read ON__INT32* p ) { @@ -973,9 +988,9 @@ ON_BinaryArchive::ReadInt32( // Read an array of 32 bit integers } bool -ON_BinaryArchive::ReadInt( // Read an array of integers - size_t count, // number of unsigned chars to read - int* p +ON_BinaryArchive::ReadInt( // Read an array of signed integers + size_t count, // number of signed chars to read + ON__INT32* p ) { #if defined(ON_COMPILER_MSC) @@ -1011,17 +1026,17 @@ ON_BinaryArchive::ReadInt( // Read an array of integers } bool -ON_BinaryArchive::ReadInt( // Read an array of 32 bit integers +ON_BinaryArchive::ReadInt( // Read an array of 32 bit unsigned integers size_t count, // number of unsigned chars to read - unsigned int* p + ON__UINT32* p ) { return ReadInt( count, (int*)p ); } bool -ON_BinaryArchive::ReadInt( // Read a single 32 bit integer - int* p +ON_BinaryArchive::ReadInt( // Read a single 32 bit signed integer + ON__INT32* p ) { return ReadInt( 1, p ); @@ -1029,13 +1044,13 @@ ON_BinaryArchive::ReadInt( // Read a single 32 bit integer bool ON_BinaryArchive::ReadInt( // Read a single 32 bit unsigned integer - unsigned int* p + ON__UINT32* p ) { return ReadInt( 1, p ); } -bool ON_BinaryArchive::ReadBigInt( // Read an array of 64 bit integers +bool ON_BinaryArchive::ReadBigInt( // Read an array of 64 bit signed integers size_t count, ON__INT64* p ) @@ -1043,7 +1058,7 @@ bool ON_BinaryArchive::ReadBigInt( // Read an array of 64 bit integers return ReadInt64(1,p); } -bool ON_BinaryArchive::ReadBigInt( // Read an array of 64 bit integers +bool ON_BinaryArchive::ReadBigInt( // Read an array of 64 bit unsigned integers size_t count, ON__UINT64* p ) @@ -1051,7 +1066,7 @@ bool ON_BinaryArchive::ReadBigInt( // Read an array of 64 bit integers return ReadInt64(1,(ON__INT64*)p); } -bool ON_BinaryArchive::ReadBigInt( // Read a single 64 bit integer +bool ON_BinaryArchive::ReadBigInt( // Read a single 64 bit signed integer ON__INT64* p ) { @@ -1068,8 +1083,8 @@ bool ON_BinaryArchive::ReadBigInt( // Read a single 64 bit unsigned integer bool -ON_BinaryArchive::ReadLong( // Read an array of 32 bit integers - size_t count, // number of unsigned chars to read +ON_BinaryArchive::ReadLong( // Read an array of 32 bit signed integers + size_t count, // number of signed integers to read long* p ) { @@ -1111,15 +1126,23 @@ ON_BinaryArchive::ReadLong( // Read an array of 32 bit integers unsigned long* p ) { +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") return ReadLong( count, (long*)p ); +#pragma ON_PRAGMA_WARNING_POP } bool -ON_BinaryArchive::ReadLong( // Read a single 32 bit integer +ON_BinaryArchive::ReadLong( // Read a single 32 bit signed integer long* p ) { +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") return ReadLong( 1, (long*)p ); +#pragma ON_PRAGMA_WARNING_POP } bool @@ -1127,7 +1150,11 @@ ON_BinaryArchive::ReadLong( // Read a single 32 bit unsigned integer unsigned long* p ) { +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") return ReadLong( 1, (long*)p ); +#pragma ON_PRAGMA_WARNING_POP } bool @@ -2159,37 +2186,7 @@ ON_BinaryArchive::ReadArray( ON_SimpleArray& a ) } bool -ON_BinaryArchive::ReadArray( ON_SimpleArray& a ) -{ - a.Empty(); - int count = 0; - bool rc = ReadInt( &count ); - if ( rc && count > 0 ) { - a.SetCapacity( count ); - rc = ReadShort( count, a.Array() ); - if ( rc ) - a.SetCount(count); - } - return rc; -} - -bool -ON_BinaryArchive::ReadArray( ON_SimpleArray& a ) -{ - a.Empty(); - int count = 0; - bool rc = ReadInt( &count ); - if ( rc && count > 0 ) { - a.SetCapacity( count ); - rc = ReadInt( count, a.Array() ); - if ( rc ) - a.SetCount(count); - } - return rc; -} - -bool -ON_BinaryArchive::ReadArray(ON_SimpleArray& a) +ON_BinaryArchive::ReadArray( ON_SimpleArray& a ) { a.Empty(); int count = 0; @@ -2204,7 +2201,52 @@ ON_BinaryArchive::ReadArray(ON_SimpleArray& a) } bool -ON_BinaryArchive::ReadArray(ON_SimpleArray& a) +ON_BinaryArchive::ReadArray( ON_SimpleArray& a ) +{ + a.Empty(); + int count = 0; + bool rc = ReadInt( &count ); + if ( rc && count > 0 ) { + a.SetCapacity( count ); + rc = ReadShort( count, a.Array() ); + if ( rc ) + a.SetCount(count); + } + return rc; +} + +bool +ON_BinaryArchive::ReadArray( ON_SimpleArray& a ) +{ + a.Empty(); + int count = 0; + bool rc = ReadInt( &count ); + if ( rc && count > 0 ) { + a.SetCapacity( count ); + rc = ReadInt( count, a.Array() ); + if ( rc ) + a.SetCount(count); + } + return rc; +} + +bool +ON_BinaryArchive::ReadArray(ON_SimpleArray& a) +{ + a.Empty(); + int count = 0; + bool rc = ReadInt(&count); + if (rc && count > 0) { + a.SetCapacity(count); + rc = ReadChar(count, a.Array()); + if (rc) + a.SetCount(count); + } + return rc; +} + +bool +ON_BinaryArchive::ReadArray(ON_SimpleArray& a) { a.Empty(); int count = 0; @@ -2219,7 +2261,7 @@ ON_BinaryArchive::ReadArray(ON_SimpleArray& a) } bool -ON_BinaryArchive::ReadArray(ON_SimpleArray& a) +ON_BinaryArchive::ReadArray(ON_SimpleArray& a) { a.Empty(); int count = 0; @@ -2775,18 +2817,35 @@ ON_BinaryArchive::WriteChar( // Write an array of 8 bit chars return WriteByte( count, p ); } +bool +ON_BinaryArchive::WriteChar( // Write a single 8 bit char + char c +) +{ + return WriteByte(1, &c); +} + +bool +ON_BinaryArchive::WriteChar( // Write an array of 8 bit signed chars + size_t count, // number of chars to write + const ON__INT8* p +) +{ + return WriteByte(count, p); +} + bool ON_BinaryArchive::WriteChar( // Write an array of 8 bit unsigned chars size_t count, // number of unsigned chars to write - const unsigned char* p + const ON__UINT8* p ) { return WriteByte( count, p ); } bool -ON_BinaryArchive::WriteChar( // Write a single 8 bit char - char c +ON_BinaryArchive::WriteChar( // Write a single 8 bit signed char + ON__INT8 c ) { return WriteByte( 1, &c ); @@ -2794,7 +2853,7 @@ ON_BinaryArchive::WriteChar( // Write a single 8 bit char bool ON_BinaryArchive::WriteChar( // Write a single 8 bit unsigned char - unsigned char c + ON__UINT8 c ) { return WriteByte( 1, &c ); @@ -2832,7 +2891,7 @@ ON_BinaryArchive::WriteInt16( // Write an array of 16 bit shorts bool ON_BinaryArchive::WriteShort( // Write an array of 16 bit shorts size_t count, // number of shorts to write - const short* p + const ON__INT16* p ) { #if defined(ON_COMPILER_MSC) @@ -2869,7 +2928,7 @@ ON_BinaryArchive::WriteShort( // Write an array of 16 bit shorts bool ON_BinaryArchive::WriteShort( // Write an array of 16 bit unsigned shorts size_t count, // number of shorts to write - const unsigned short* p + const ON__UINT16* p ) { return WriteShort( count, (const short*)p ); @@ -2877,7 +2936,7 @@ ON_BinaryArchive::WriteShort( // Write an array of 16 bit unsigned shorts bool ON_BinaryArchive::WriteShort( // Write a single 16 bit short - short s + ON__INT16 s ) { return WriteShort( 1, &s ); @@ -2885,7 +2944,7 @@ ON_BinaryArchive::WriteShort( // Write a single 16 bit short bool ON_BinaryArchive::WriteShort( // Write a single 16 bit unsigned short - unsigned short s + ON__UINT16 s ) { return WriteShort( 1, &s ); @@ -2978,7 +3037,7 @@ ON_BinaryArchive::WriteInt64( // Write an array of 64 bit integers bool ON_BinaryArchive::WriteInt( // Write an array of integers size_t count, // number of ints to write - const int* p + const ON__INT32* p ) { #if defined(ON_COMPILER_MSC) @@ -3032,7 +3091,7 @@ ON_BinaryArchive::ReadSize(size_t* sz) bool ON_BinaryArchive::WriteBigSize(size_t sz) { ON__UINT64 u = (ON__UINT64)sz; - return WriteInt64(1,(ON__INT64*)&u);; + return WriteInt64(1,(ON__INT64*)&u); } bool ON_BinaryArchive::ReadBigSize( size_t* sz ) @@ -3063,23 +3122,23 @@ bool ON_BinaryArchive::ReadBigTime( time_t* t ) bool ON_BinaryArchive::WriteInt( // Write an array of 32 bit integers size_t count, // number of ints to write - const unsigned int* p + const ON__UINT32* p ) { return WriteInt( count, (const int*)p ); } bool -ON_BinaryArchive::WriteInt( // Write a single 32 bit integer - int i +ON_BinaryArchive::WriteInt( // Write a single 32 bit signed integer + ON__INT32 i ) { return WriteInt( 1, &i ); } bool -ON_BinaryArchive::WriteInt( // Write a single 32 bit integer - unsigned int i +ON_BinaryArchive::WriteInt( // Write a single 32 bit unsigned integer + ON__UINT32 i ) { return WriteInt( 1, &i ); @@ -3160,7 +3219,11 @@ ON_BinaryArchive::WriteLong( // Write an array of longs const unsigned long* p ) { +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") return WriteLong( count, (const long*)p ); +#pragma ON_PRAGMA_WARNING_POP } bool @@ -3168,7 +3231,11 @@ ON_BinaryArchive::WriteLong( // Write a single long long i ) { +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") return WriteLong( 1, &i ); +#pragma ON_PRAGMA_WARNING_POP } bool @@ -3176,7 +3243,11 @@ ON_BinaryArchive::WriteLong( // Write a single unsigned long unsigned long i ) { +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") return WriteLong( 1, &i ); +#pragma ON_PRAGMA_WARNING_POP } @@ -3862,7 +3933,20 @@ ON_BinaryArchive::WriteArray( const ON_SimpleArray& a ) } bool -ON_BinaryArchive::WriteArray( const ON_SimpleArray& a ) +ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) +{ + int count = a.Count(); + if (count < 0) + count = 0; + bool rc = WriteInt(count); + if (rc && count > 0) { + rc = WriteChar(count, a.Array()); + } + return rc; +} + +bool +ON_BinaryArchive::WriteArray( const ON_SimpleArray& a ) { int count = a.Count(); if ( count < 0 ) @@ -3875,7 +3959,7 @@ ON_BinaryArchive::WriteArray( const ON_SimpleArray& a ) } bool -ON_BinaryArchive::WriteArray( const ON_SimpleArray& a ) +ON_BinaryArchive::WriteArray( const ON_SimpleArray& a ) { int count = a.Count(); if ( count < 0 ) @@ -3889,7 +3973,7 @@ ON_BinaryArchive::WriteArray( const ON_SimpleArray& a ) bool -ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) +ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) { int count = a.Count(); if (count < 0) @@ -3902,7 +3986,7 @@ ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) } bool -ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) +ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) { int count = a.Count(); if (count < 0) @@ -3915,7 +3999,7 @@ ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) } bool -ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) +ON_BinaryArchive::WriteArray(const ON_SimpleArray& a) { int count = a.Count(); if (count < 0) diff --git a/opennurbs_archive.h b/opennurbs_archive.h index 1006bf08..fd9adc1d 100644 --- a/opennurbs_archive.h +++ b/opennurbs_archive.h @@ -2118,45 +2118,53 @@ public: size_t, // number of chars to read char* ); - bool ReadChar( // Read an array of 8 bit unsigned chars - size_t, // number of unsigned chars to read - unsigned char* - ); bool ReadChar( // Read a single 8 bit char char* ); + + bool ReadChar( // Read an array of 8 bit signed chars + size_t, // number of chars to read + ON__INT8* + ); + bool ReadChar( // Read an array of 8 bit unsigned chars + size_t, // number of unsigned chars to read + ON__UINT8* + ); + bool ReadChar( // Read a single 8 bit signed char + ON__INT8* + ); bool ReadChar( // Read a single 8 bit unsigned char - unsigned char* + ON__UINT8* ); bool ReadShort( // Read an array of 16 bit shorts size_t, // number of shorts to read - short* + ON__INT16* ); bool ReadShort( // Read an array of 16 bit unsigned shorts size_t, // number of shorts to read - unsigned short* + ON__UINT16* ); bool ReadShort( // Read a single 16 bit short - short* + ON__INT16* ); bool ReadShort( // Read a single 16 bit unsigned short - unsigned short* + ON__UINT16* ); bool ReadInt( // Read an array of 32 bit integers size_t, // number of ints to read - int* + ON__INT32* ); bool ReadInt( // Read an array of 32 bit integers size_t, // number of ints to read - unsigned int* + ON__UINT32* ); bool ReadInt( // Read a single 32 bit integer - int* + ON__INT32* ); bool ReadInt( // Read a single 32 bit unsigned integer - unsigned int* + ON__UINT32* ); bool ReadBigInt( // Read an array of 64 bit integers @@ -2174,21 +2182,33 @@ public: ON__UINT64* ); + + ON_DEPRECATED_MSG("Please use ON_BinaryArchive::ReadInt") bool ReadLong( // Read an array of 32 bit integers size_t, // number of ints to read long* ); + ON_DEPRECATED_MSG("Please use ON_BinaryArchive::ReadInt") bool ReadLong( // Read an array of 32 bit integers size_t, // number of ints to read unsigned long* ); + ON_DEPRECATED_MSG("Please use ON_BinaryArchive::ReadInt") bool ReadLong( // Read a single 32 bit integer long* ); + ON_DEPRECATED_MSG("Please use ON_BinaryArchive::ReadInt") bool ReadLong( // Read a single 32 bit unsigned integer unsigned long* ); - bool ReadSize( // Read a single size_t + + ON_DEPRECATED_MSG + ( + "ON_BinaryArchive::ReadSize is deprecated because it truncates to 32-bits.\n" + " - If you are updating existing code use 'ReadInt' instead.\n" + " - Else if you need to write a 64-bit size_t please call 'ReadBigSize'" + ) + bool ReadSize( // Read a single 32 bit size_t size_t* ); @@ -2367,14 +2387,17 @@ public: bool ReadComponentIndex( ON_COMPONENT_INDEX& ); bool ReadArray( ON_SimpleArray& ); - bool ReadArray(ON_SimpleArray&); - bool ReadArray(ON_SimpleArray&); - bool ReadArray(ON_SimpleArray&); - bool ReadArray(ON_SimpleArray&); - bool ReadArray(ON_SimpleArray&); - bool ReadArray(ON_SimpleArray&); + bool ReadArray( ON_SimpleArray&); + + bool ReadArray( ON_SimpleArray&); + bool ReadArray( ON_SimpleArray&); + bool ReadArray( ON_SimpleArray&); + bool ReadArray( ON_SimpleArray&); + bool ReadArray( ON_SimpleArray&); + bool ReadArray( ON_SimpleArray&); bool ReadArray( ON_SimpleArray& ); bool ReadArray( ON_SimpleArray& ); + bool ReadArray( ON_SimpleArray& ); bool ReadArray( ON_SimpleArray& ); bool ReadArray( ON_SimpleArray& ); @@ -2422,45 +2445,53 @@ public: size_t, // number of chars to write const char* ); - bool WriteChar( // Write an array of 8 bit unsigned chars - size_t, // number of unsigned chars to write - const unsigned char* - ); bool WriteChar( // Write a single 8 bit char char ); + + bool WriteChar( // Write an array of 8 bit signed chars + size_t, // number of chars to write + const ON__INT8* + ); + bool WriteChar( // Write an array of 8 bit unsigned chars + size_t, // number of unsigned chars to write + const ON__UINT8* + ); + bool WriteChar( // Write a single 8 bit signed char + ON__INT8 + ); bool WriteChar( // Write a single 8 bit unsigned char - unsigned char + ON__UINT8 ); bool WriteShort( // Write an array of 16 bit shorts size_t, // number of shorts to write - const short* + const ON__INT16* ); bool WriteShort( // Write an array of 16 bit unsigned shorts size_t, // number of shorts to write - const unsigned short* + const ON__UINT16* ); bool WriteShort( // Write a single 16 bit short - short + ON__INT16 ); bool WriteShort( // Write a single 16 bit unsigned short - unsigned short + ON__UINT16 ); bool WriteInt( // Write an array of 32 bit integers size_t, // number of ints to write - const int* + const ON__INT32* ); bool WriteInt( // Write an array of 32 bit integers size_t, // number of ints to write - const unsigned int* + const ON__UINT32* ); bool WriteInt( // Write a single 32 bit integer - int + ON__INT32 ); bool WriteInt( // Write a single 32 bit unsigned integer - unsigned int + ON__UINT32 ); bool WriteBigInt( // Write an array of 64 bit integers @@ -2478,21 +2509,32 @@ public: ON__UINT64 ); + ON_DEPRECATED_MSG("Please use ON_BinaryArchive::WriteInt") bool WriteLong( // Write an array of 32 bit integers size_t, // number of ints to write const long* ); + ON_DEPRECATED_MSG("Please use ON_BinaryArchive::WriteInt") bool WriteLong( // Write an array of 32 bit integers size_t, // number of ints to write const unsigned long* ); + ON_DEPRECATED_MSG("Please use ON_BinaryArchive::WriteInt") bool WriteLong( // Write a single 32 bit integer long ); + ON_DEPRECATED_MSG("Please use ON_BinaryArchive::WriteInt") bool WriteLong( // Write a single 32 bit unsigned integer unsigned long ); - bool WriteSize( // Write a single size_t + + ON_DEPRECATED_MSG + ( + "ON_BinaryArchive::WriteSize is deprecated because it truncates to 32-bits.\n" + " - If you are updating existing code use 'WriteInt' instead.\n" + " - Else if you need to write a 64-bit size_t please call 'WriteBigSize'" + ) + bool WriteSize( // Write a single 32 bit size_t size_t ); @@ -2664,12 +2706,13 @@ public: bool WriteArray( const ON_SimpleArray& ); bool WriteArray( const ON_SimpleArray& ); - bool WriteArray( const ON_SimpleArray& ); - bool WriteArray( const ON_SimpleArray& ); - - bool WriteArray(const ON_SimpleArray&); - bool WriteArray(const ON_SimpleArray&); - bool WriteArray(const ON_SimpleArray&); + + bool WriteArray( const ON_SimpleArray& ); + bool WriteArray( const ON_SimpleArray& ); + bool WriteArray( const ON_SimpleArray& ); + bool WriteArray(const ON_SimpleArray&); + bool WriteArray(const ON_SimpleArray&); + bool WriteArray(const ON_SimpleArray&); bool WriteArray( const ON_SimpleArray& ); bool WriteArray( const ON_SimpleArray& ); diff --git a/opennurbs_array.h b/opennurbs_array.h index a1f82bfc..344aad48 100644 --- a/opennurbs_array.h +++ b/opennurbs_array.h @@ -386,21 +386,23 @@ protected: ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; -ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; +ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; diff --git a/opennurbs_bitmap.cpp b/opennurbs_bitmap.cpp index b443bb98..216a4b55 100644 --- a/opennurbs_bitmap.cpp +++ b/opennurbs_bitmap.cpp @@ -1238,8 +1238,12 @@ bool ON_EmbeddedBitmap::Internal_ReadV5( ON_BinaryArchive& file ) if (0 == i) { // uncompressed +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") if (!file.ReadSize(&m_sizeof_buffer)) break; +#pragma ON_PRAGMA_WARNING_POP void* buffer = nullptr; if (m_sizeof_buffer > 0) { diff --git a/opennurbs_bounding_box.cpp b/opennurbs_bounding_box.cpp index 6d943e6e..6f7e72f3 100644 --- a/opennurbs_bounding_box.cpp +++ b/opennurbs_bounding_box.cpp @@ -518,7 +518,7 @@ int ON_ClippingRegion::InClipPlaneRegion( if ( x < -clip_plane_tolerance ) out |= cpbit; cpbit <<= 1; - cpeqn++;; + cpeqn++; } } some_out |= out; @@ -582,7 +582,7 @@ int ON_ClippingRegion::InClipPlaneRegion( if ( x < -clip_plane_tolerance ) out |= cpbit; cpbit <<= 1; - cpeqn++;; + cpeqn++; } } some_out |= out; @@ -646,7 +646,7 @@ int ON_ClippingRegion::InClipPlaneRegion( if ( x < -clip_plane_tolerance ) out |= cpbit; cpbit <<= 1; - cpeqn++;; + cpeqn++; } } some_out |= out; @@ -732,7 +732,7 @@ int ON_ClippingRegion::IsVisible( int count, const ON_3fPoint* p ) const if ( x < -clip_plane_tolerance ) out |= cpbit; cpbit <<= 1; - cpeqn++;; + cpeqn++; } } w = xform[12]*cv[0] + xform[13]*cv[1] + xform[14]*cv[2] + xform[15]; @@ -796,7 +796,7 @@ int ON_ClippingRegion::IsVisible( int count, const ON_3dPoint* p ) const if ( x < -clip_plane_tolerance ) out |= cpbit; cpbit <<= 1; - cpeqn++;; + cpeqn++; } } w = xform[12]*cv[0] + xform[13]*cv[1] + xform[14]*cv[2] + xform[15]; @@ -1036,7 +1036,7 @@ int ON_ClippingRegion::TransformPoints( int count, ON_4dPoint* p, unsigned int* if ( x < -clip_plane_tolerance ) out |= cpbit; cpbit <<= 1; - cpeqn++;; + cpeqn++; } } w = xform[12]*cv[0] + xform[13]*cv[1] + xform[14]*cv[2] + xform[15]*cv[3]; @@ -1101,7 +1101,7 @@ int ON_ClippingRegion::TransformPoints( int count, ON_4dPoint* p ) const if ( x < -clip_plane_tolerance ) out |= cpbit; cpbit <<= 1; - cpeqn++;; + cpeqn++; } } w = xform[12]*cv[0] + xform[13]*cv[1] + xform[14]*cv[2] + xform[15]*cv[3]; diff --git a/opennurbs_brep_tools.cpp b/opennurbs_brep_tools.cpp index 7d5f1be3..3658f852 100644 --- a/opennurbs_brep_tools.cpp +++ b/opennurbs_brep_tools.cpp @@ -268,7 +268,7 @@ bool ON_Brep::SetTrimBoundingBoxes( bool bLazy ) bool ON_Brep::SetTrimBoundingBoxes( ON_BrepFace& face, bool bLazy ) { bool rc = true; - int li, fli, loop_count = m_L.Count(), fl_count = face.m_li.Count();; + int li, fli, loop_count = m_L.Count(), fl_count = face.m_li.Count(); for ( fli = 0; fli < fl_count; fli++ ) { li = face.m_li[fli]; diff --git a/opennurbs_current_environment.cpp b/opennurbs_current_environment.cpp deleted file mode 100644 index c77df4c3..00000000 --- a/opennurbs_current_environment.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* -// -// Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved. -// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert -// McNeel & Associates. -// -// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. -// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF -// MERCHANTABILITY ARE HEREBY DISCLAIMED. -// -// For complete openNURBS copyright information see . -// -//////////////////////////////////////////////////////////////// -*/ - -#include "opennurbs.h" -#include "opennurbs_internal_defines.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. -// When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined -// and the opennurbs .h files alter what is declared and how it is declared. -#error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs -#endif - -// This is inside the ON_RDK_CURRENT_CONTENT section. -#define ON_RDK_BACKGROUND_ENVIRONMENT L"environment" - -// These are inside the ON_RDK_RENDERING section. -#define ON_RDK_CUSTOM_REFLECTIVE_ENVIRONMENT_ON L"custom-env-for-refl-and-refr-on" -#define ON_RDK_CUSTOM_REFLECTIVE_ENVIRONMENT L"custom-env-for-refl-and-refr" - -// These are inside the ON_RDK_SUN section. -#define ON_RDK_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT_ON L"skylight-custom-environment-on" -#define ON_RDK_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT L"skylight-custom-environment" - -class ON_CurrentEnvironment::CImpl : public ON_InternalXMLImpl -{ -public: - CImpl() { } - CImpl(ON_XMLNode& model_node, ON_3dmRenderSettings& rs) : m_rs(&rs), ON_InternalXMLImpl(&model_node) { } - - ON_3dmRenderSettings* m_rs = nullptr; - bool m_on = false; // Only used if m_rs is null. -}; - -static const wchar_t* XMLPathBack360(void) // Not used for 'on'. -{ - return ON_RDK_DOCUMENT ON_RDK_SLASH ON_RDK_CURRENT_CONTENT; -} - -static const wchar_t* XMLPathReflRefr(void) -{ - return ON_RDK_DOCUMENT ON_RDK_SLASH ON_RDK_SETTINGS ON_RDK_SLASH ON_RDK_RENDERING; -} - -static const wchar_t* XMLPathSkylight(void) -{ - return ON_RDK_DOCUMENT ON_RDK_SLASH ON_RDK_SETTINGS ON_RDK_SLASH ON_RDK_SUN; -} - -ON_CurrentEnvironment::ON_CurrentEnvironment() -{ - m_impl = new CImpl; -} - -ON_CurrentEnvironment::ON_CurrentEnvironment(ON_XMLNode& model_node, ON_3dmRenderSettings& rs) -{ - m_impl = new CImpl(model_node, rs); -} - -ON_CurrentEnvironment::ON_CurrentEnvironment(const ON_CurrentEnvironment& ce) -{ - m_impl = new CImpl; - operator = (ce); -} - -ON_CurrentEnvironment::~ON_CurrentEnvironment() -{ - delete m_impl; - m_impl = nullptr; -} - -const ON_CurrentEnvironment& ON_CurrentEnvironment::operator = (const ON_CurrentEnvironment& ce) -{ - if (this != &ce) - { - SetOn(Usage::Background, ce.On (Usage::Background)); - SetOn(Usage::Reflection, ce.On (Usage::Reflection)); - SetOn(Usage::Skylighting, ce.On (Usage::Skylighting)); - - Set (Usage::Background, ce.Get(Usage::Background)); - Set (Usage::Reflection, ce.Get(Usage::Reflection)); - Set (Usage::Skylighting, ce.Get(Usage::Skylighting)); - } - - return *this; -} - -bool ON_CurrentEnvironment::operator == (const ON_CurrentEnvironment& ce) -{ - if (On (Usage::Background) != ce.On (Usage::Background)) return false; - if (On (Usage::Reflection) != ce.On (Usage::Reflection)) return false; - if (On (Usage::Skylighting) != ce.On (Usage::Skylighting)) return false; - - if (Get(Usage::Background) != ce.Get(Usage::Background)) return false; - if (Get(Usage::Reflection) != ce.Get(Usage::Reflection)) return false; - if (Get(Usage::Skylighting) != ce.Get(Usage::Skylighting)) return false; - - return true; -} - -bool ON_CurrentEnvironment::operator != (const ON_CurrentEnvironment& sf) -{ - return !(operator == (sf)); -} - -bool ON_CurrentEnvironment::On(Usage usage) const -{ - switch (usage) - { - case Usage::Background: - if (nullptr != m_impl->m_rs) - return (3 == m_impl->m_rs->m_background_style); - return m_impl->m_on; - - case Usage::Reflection: - return m_impl->GetParameter(XMLPathReflRefr(), ON_RDK_CUSTOM_REFLECTIVE_ENVIRONMENT_ON, false); - - case Usage::Skylighting: - return m_impl->GetParameter(XMLPathSkylight(), ON_RDK_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT_ON, false); - } - - return false; -} - -void ON_CurrentEnvironment::SetOn(Usage usage, bool on) -{ - switch (usage) - { - case Usage::Background: - if (nullptr != m_impl->m_rs) // I'm not sure if this is correct. - ON_ERROR("Unable to set the 360 env on state. The env is on when render settings m_background_mode is 3."); - else - m_impl->m_on = on; - break; - - case Usage::Reflection: - m_impl->SetParameter(XMLPathReflRefr(), ON_RDK_CUSTOM_REFLECTIVE_ENVIRONMENT_ON, on); - break; - - case Usage::Skylighting: - m_impl->SetParameter(XMLPathSkylight(), ON_RDK_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT_ON, on); - break; - } -} - -ON_UUID ON_CurrentEnvironment::Get(Usage usage) const -{ - switch (usage) - { - case Usage::Background: // This uses old-school XML without the type property. - return m_impl->GetParameter_NoType(XMLPathBack360(), ON_RDK_BACKGROUND_ENVIRONMENT, L"uuid", ON_nil_uuid); - - case Usage::Reflection: - return m_impl->GetParameter(XMLPathReflRefr(), ON_RDK_CUSTOM_REFLECTIVE_ENVIRONMENT, ON_nil_uuid); - - case Usage::Skylighting: - return m_impl->GetParameter(XMLPathSkylight(), ON_RDK_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT, ON_nil_uuid); - } - - return ON_nil_uuid; -} - -void ON_CurrentEnvironment::Set(Usage usage, const ON_UUID& uuid) -{ - switch (usage) - { - case Usage::Background: // This uses old-school XML without the type property. - m_impl->SetParameter_NoType(XMLPathBack360(), ON_RDK_BACKGROUND_ENVIRONMENT, uuid); - break; - - case Usage::Reflection: - m_impl->SetParameter(XMLPathReflRefr(), ON_RDK_CUSTOM_REFLECTIVE_ENVIRONMENT, uuid); - break; - - case Usage::Skylighting: - m_impl->SetParameter(XMLPathSkylight(), ON_RDK_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT, uuid); - break; - } -} diff --git a/opennurbs_current_environment.h b/opennurbs_current_environment.h deleted file mode 100644 index 56489663..00000000 --- a/opennurbs_current_environment.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -// -// Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved. -// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert -// McNeel & Associates. -// -// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. -// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF -// MERCHANTABILITY ARE HEREBY DISCLAIMED. -// -// For complete openNURBS copyright information see . -// -//////////////////////////////////////////////////////////////// -*/ - -#if !defined(ON_CURRENT_ENVIRONMENT_INC_) -#define ON_CURRENT_ENVIRONMENT_INC_ - -class ON_CLASS ON_CurrentEnvironment final -{ -public: - ON_CurrentEnvironment(); - ON_CurrentEnvironment(ON_XMLNode& model_node, ON_3dmRenderSettings& rs); - ON_CurrentEnvironment(const ON_CurrentEnvironment& ce); - ~ON_CurrentEnvironment(); - - const ON_CurrentEnvironment& operator = (const ON_CurrentEnvironment& lw); - - bool operator == (const ON_CurrentEnvironment& lw); - bool operator != (const ON_CurrentEnvironment& lw); - - enum class Usage : unsigned int - { - Background, // Specifies the background environment. - Reflection, // Specifies the custom reflective environment. Also used for refraction. - Skylighting, // Specifies the custom skylighting environment. - }; - - // Get if the current environment is 'on' for a particular usage. - bool On(Usage usage) const; - - // Set if the current environment is 'on' for a particular usage. - void SetOn(Usage usage, bool bOn); - - // Get the current environment instance id. If there is no current environment, - // the function returns the default environment's instance id. */ - ON_UUID Get(Usage usage) const; - - // Set the current environment instance id for a specific usage. Note that passing ON_nil_uuid - // for a usage will remove that specialization. - void Set(Usage usage, const ON_UUID& uuidInstance); - -public: - class CImpl; - CImpl* m_impl; -}; - -#endif diff --git a/opennurbs_decals.cpp b/opennurbs_decals.cpp index ce31d8d8..40996145 100644 --- a/opennurbs_decals.cpp +++ b/opennurbs_decals.cpp @@ -68,10 +68,10 @@ class ON_Decal::CImpl : public ON_InternalXMLImpl { public: - CImpl() { ON_CreateUuid(m_uuid); } - CImpl(ON_XMLNode& n) : ON_InternalXMLImpl(&n) { ON_CreateUuid(m_uuid); } + CImpl() { ON_CreateUuid(m_decal_id); } + CImpl(ON_XMLNode& n) { ON_CreateUuid(m_decal_id); Node() = n; } - ON_UUID m_uuid; + ON_UUID m_decal_id; }; static const wchar_t* XMLPath(void) @@ -183,7 +183,7 @@ void ON_Decal::SetTextureInstanceId(const ON_UUID& id) ON_Decal::Mappings ON_Decal::Mapping(void) const { - const auto s = m_impl->GetParameter(XMLPath(), ON_RDK_UD_DECAL_MAPPING, ON_RDK_UD_DECAL_MAPPING_UV).AsString(); + const ON_wString s = m_impl->GetParameter(XMLPath(), ON_RDK_UD_DECAL_MAPPING, ON_RDK_UD_DECAL_MAPPING_UV).AsString(); if (ON_RDK_UD_DECAL_MAPPING_UV == s) return ON_Decal::Mappings::UV; @@ -217,7 +217,7 @@ void ON_Decal::SetMapping(Mappings m) ON_Decal::Projections ON_Decal::Projection(void) const { - const auto s = m_impl->GetParameter(XMLPath(), ON_RDK_UD_DECAL_PROJECTION, ON_RDK_UD_DECAL_PROJECTION_FORWARD).AsString(); + const ON_wString s = m_impl->GetParameter(XMLPath(), ON_RDK_UD_DECAL_PROJECTION, ON_RDK_UD_DECAL_PROJECTION_FORWARD).AsString(); if (ON_RDK_UD_DECAL_PROJECTION_FORWARD == s) return ON_Decal::Projections::Forward; @@ -362,201 +362,22 @@ ON__UINT32 ON_Decal::DataCRC(ON__UINT32 crc) const ON_UUID ON_Decal::Id(void) const { - return m_impl->m_uuid; + return m_impl->m_decal_id; +} + +const ON_XMLNode& ON_Decal::XML(void) const +{ + return m_impl->Node(); } // ON_DecalCollection ON_DecalCollection::~ON_DecalCollection() -{ - for (int i = 0; i < m_items.Count(); i++) - { - delete m_items[i]; - } -} - -void ON_DecalCollection::CreateDecalsFromXML(const ONX_Model& model, int archive_3dm_version) -{ - ONX_ModelComponentIterator cit(model, ON_ModelComponent::Type::ModelGeometry); - const auto* component = cit.FirstComponent(); - for (; nullptr != component; component = cit.NextComponent()) - { - auto* attr = GetComponentAttributes(*component); - if (nullptr == attr) - continue; // No attributes on component. - - // Get the entire XML off of the attributes user data. - ON_wString xml; - GetRDKObjectInformation(*attr, xml, archive_3dm_version); - if (xml.IsEmpty()) - continue; // No XML found on the component's attributes. - - // Create a new item for this component. - auto* item = new Item(component->Id()); - - // Set the XML to the item. The XML is the node including (among other possible things) - // all the decals on this component. - item->SetXML(xml.Array()); - - // Append the item to the collection. - m_items.Append(item); - } -} - -void ON_DecalCollection::CreateXMLFromDecals(const ONX_Model& model, int archive_3dm_version) -{ - for (int i = 0; i < m_items.Count(); i++) - { - auto* item = m_items[i]; - - const auto& mgc = model.ModelGeometryComponentFromId(item->ComponentId()); - ON_ASSERT(mgc.ComponentType() == ON_ModelComponent::Type::ModelGeometry); - - // Decals are stored on the user data of object attributes. - auto* attr = const_cast(mgc.Attributes(nullptr)); - if (nullptr == attr) - continue; // Should never happen because we have an item for the object. - - // Get the new decals XML as a string. - const auto decals_xml = item->DecalsXML(); - - // Get the entire XML off of the attributes user data. - ON_XMLRootNode root; - - ON_wString xml; - GetRDKObjectInformation(*attr, xml, archive_3dm_version); - if (xml.IsNotEmpty()) - { - if (ON_XMLNode::ReadError == root.ReadFromStream(xml)) - continue; // Invalid XML. Should never happen. - } - - // Find any existing decals node, creating it if not found. - // This also ensures that the necessary parent nodes exist. - const auto* path = ON_RDK_UD_ROOT ON_RDK_SLASH ON_RDK_UD_DECALS; - auto* old_decals_node = root.CreateNodeAtPath(path); // Never null. - - // Get the parent node of the decals node. - auto* parent_node = old_decals_node->GetParent(); - - // Delete the existing decals node. - delete parent_node->DetachChild(*old_decals_node); - - if (decals_xml.IsNotEmpty()) - { - // Attach a new decals node to the parent node and read it from the decals XML. - auto* new_decals_node = parent_node->AttachChildNode(new ON_XMLNode(L"")); - new_decals_node->ReadFromStream(decals_xml); - - // Set the item's XML to the attributes user data. - SetRDKObjectInformation(*attr, root.String(), archive_3dm_version); - } - } -} - -int ON_DecalCollection::FindItemIndex(const ON_UUID& component_id) const -{ - for (int i = 0; i < m_items.Count(); i++) - { - if (m_items[i]->ComponentId() == component_id) - return i; - } - - return -1; -} - -ON_DecalCollection::Item* ON_DecalCollection::FindItem(const ON_UUID& component_id) const -{ - const auto index = FindItemIndex(component_id); - if (index >= 0) - return m_items[index]; - - return nullptr; -} - -ON_DecalCollection::Item* ON_DecalCollection::ItemAt(int index) const -{ - if ((index < 0) || (index >= m_items.Count())) - return nullptr; - - return m_items[index]; -} - -int ON_DecalCollection::ItemCount(void) const -{ - return m_items.Count(); -} - -ON_Decal* ON_DecalCollection::AddDecal(const ON_ModelComponent& component) -{ - ON_XMLNode decals_node(ON_RDK_UD_DECALS); - - // See if there's already an item for this component. - auto* item = FindItem(component.Id()); - if (nullptr != item) - { - // Yes, so load the item's current XML into 'decals_node'. - decals_node.ReadFromStream(item->DecalsXML()); - } - else - { - // Decals are stored on the user data of object attributes. - if (nullptr == GetComponentAttributes(component)) - return nullptr; // No attributes on component. - - // Create a new item for this component. - item = new Item(component.Id()); - - // Append the item to the collection. - m_items.Append(item); - } - - // Count the number of existing decal nodes. This will be the index of the new decal. - int index = 0; - auto it = decals_node.GetChildIterator(); - ON_XMLNode* child_node = nullptr; - while (nullptr != (child_node = it.GetNextChild())) - { - index++; - } - - // Attach a child node for the new decal. - decals_node.AttachChildNode(new ON_XMLNode(ON_RDK_UD_DECAL)); - - // Set the XML to the item. - item->SetDecalsXML(decals_node); - - // Return the decal just added. - return item->GetDecal(index); -} - -ON_Decal* ON_DecalCollection::GetDecal(const ON_UUID& id) -{ - for (int i = 0; i < m_items.Count(); i++) - { - auto* decal = m_items[i]->GetDecal(id); - if (nullptr != decal) - return decal; - } - - return nullptr; -} - -// ON_DecalCollection::Item - -ON_DecalCollection::Item::Item(const ON_UUID& cid) - : - m_decals_node(L""), - m_component_id(cid) -{ -} - -ON_DecalCollection::Item::~Item() { DeleteAllDecals(); } -void ON_DecalCollection::Item::DeleteAllDecals(void) +void ON_DecalCollection::DeleteAllDecals(void) { for (int i = 0; i < m_decals.Count(); i++) { @@ -566,167 +387,121 @@ void ON_DecalCollection::Item::DeleteAllDecals(void) m_decals.Destroy(); } -ON_wString ON_DecalCollection::Item::DecalsXML(void) const -{ - return m_decals_node.String(); -} - -bool ON_DecalCollection::Item::SetXML(const wchar_t* xml) -{ - ON_XMLRootNode root; - if (!root.ReadFromStream(xml)) - return false; - - const auto* path = ON_RDK_UD_ROOT ON_RDK_SLASH ON_RDK_UD_DECALS; - auto* decals_node = root.GetNodeAtPath(path); - if (nullptr == decals_node) - return false; // No decals in the item. - - return SetDecalsXML(*decals_node); -} - -bool ON_DecalCollection::Item::SetDecalsXML(const ON_XMLNode& decals_node) +const ON_DecalCollection& ON_DecalCollection::operator = (const ON_DecalCollection& dc) { DeleteAllDecals(); - m_decals_node = decals_node; + for (int i = 0; i < dc.m_decals.Count(); i++) + { + ON_Decal* decal = dc.m_decals[i]; + if (nullptr != decal) + { + m_decals.Append(new ON_Decal(*decal)); + } + } + + return *this; +} + +bool ON_DecalCollection::NodeContainsDecals(const ON_XMLRootNode& node) // Static. +{ + const wchar_t* path = ON_RDK_UD_ROOT ON_RDK_SLASH ON_RDK_UD_DECALS; + const ON_XMLNode* decals_node = node.GetNodeAtPath(path); + if (nullptr == decals_node) + return false; + + if (nullptr == decals_node->GetNamedChild(ON_RDK_UD_DECAL)) + return false; + + return true; +} + +void ON_DecalCollection::Populate(const ON_XMLRootNode& node) +{ + DeleteAllDecals(); + + const wchar_t* path = ON_RDK_UD_ROOT ON_RDK_SLASH ON_RDK_UD_DECALS; + ON_XMLNode* decals_node = node.GetNodeAtPath(path); + if (nullptr == decals_node) + return; // No decals. // Iterate over the decals under the decals node adding a new decal for each one. - // The decals store the pointer to their node inside the decals node in the collection. - // This is safe because the decals have the same lifetime as the collection. - auto it = m_decals_node.GetChildIterator(); + // The decals copy the node into a local node which holds the XML for each decal + // in that decal. This XML will be modified by the decal setters and then repacked + // into the attribute user data later during the save process. + auto it = decals_node->GetChildIterator(); ON_XMLNode* child_node = nullptr; while (nullptr != (child_node = it.GetNextChild())) { m_decals.Append(new ON_Decal(*child_node)); } - - return true; } -ON_Decal* ON_DecalCollection::Item::GetDecal(int index) const +ON_Decal* ON_DecalCollection::AddDecal(void) { - if (index >= m_decals.Count()) - return nullptr; + ON_XMLNode node(ON_RDK_UD_DECAL); + auto* decal = new ON_Decal(node); + m_decals.Append(decal); - return m_decals[index]; + return decal; } -ON_Decal* ON_DecalCollection::Item::GetDecal(const ON_UUID& id) const +void CreateDecalsFromXML(const ONX_Model& model, int archive_3dm_version) { - for (int i = 0; i < m_decals.Count(); i++) + ONX_ModelComponentIterator cit(model, ON_ModelComponent::Type::ModelGeometry); + + for (const ON_ModelComponent* component = cit.FirstComponent(); nullptr != component; component = cit.NextComponent()) { - auto* decal = m_decals[i]; - if (decal->Id() == id) - return decal; - } + const ON_3dmObjectAttributes* attr = GetComponentAttributes(*component); + if (nullptr == attr) + continue; // No attributes on component. - return nullptr; -} + // Get the entire XML off of the attributes user data. + ON_wString xml; + GetRDKObjectInformation(*attr, xml, archive_3dm_version); + if (xml.IsEmpty()) + continue; // No XML found on the component's attributes. -// ON_DecalIterator - -class ON_DecalIterator::CImpl -{ -public: - CImpl(ONX_Model& model) : m_model(model) { } - virtual ~CImpl() { } - - virtual ON_Decal* Next(void) = 0; - -protected: - ONX_Model& m_model; - int m_decal_index = -1; -}; - -class CImpl_PerComponent : public ON_DecalIterator::CImpl -{ -public: - CImpl_PerComponent(ONX_Model& model, const ON_ModelComponent& component) - : - CImpl(model) - { - m_component_id = component.Id(); - } - - virtual ON_Decal* Next(void) override - { - if (nullptr == m_item) + ON_XMLRootNode node; + if (ON_XMLNode::ReadError != node.ReadFromStream(xml)) { - const auto& collection = GetDecalCollection(m_model); - - m_item = collection.FindItem(m_component_id); - if (nullptr == m_item) - return nullptr; - - m_decal_index = 0; + attr->Internal_PopulateDecals(node); } - - return m_item->GetDecal(m_decal_index++); - } - -public: - ON_UUID m_component_id; - ON_DecalCollection::Item* m_item = nullptr; -}; - -class CImpl_All : public ON_DecalIterator::CImpl -{ -public: - CImpl_All(ONX_Model& model) : CImpl(model) { } - - virtual ON_Decal* Next(void) override - { - if (!m_populated) + else { - const auto& collection = GetDecalCollection(m_model); + ON_ERROR("Failed to read decal XML"); + } + } +} - for (int i = 0; i < collection.ItemCount(); i++) +void CreateXMLFromDecals(const ONX_Model& model, int archive_3dm_version) +{ + ONX_ModelComponentIterator cit(model, ON_ModelComponent::Type::ModelGeometry); + + for (const ON_ModelComponent* component = cit.FirstComponent(); nullptr != component; component = cit.NextComponent()) + { + ON_3dmObjectAttributes* attr = GetComponentAttributes(*component); + if (nullptr == attr) + continue; // No attributes on component. + + const ON_SimpleArray& decals = attr->GetDecalArray(); + if (decals.Count() == 0) + continue; // No decals on attributes. + + ON_XMLRootNode root; + ON_XMLNode* decals_node = root.CreateNodeAtPath(ON_RDK_UD_ROOT ON_RDK_SLASH ON_RDK_UD_DECALS); + if (nullptr == decals_node) + continue; // Failed to create node -- not likely to happen. + + for (int i = 0; i < decals.Count(); i++) + { + const ON_Decal* decal = decals[i]; + if (nullptr != decal) { - const auto* item = collection.ItemAt(i); - - int d = 0; - ON_Decal* decal = nullptr; - while (nullptr != (decal = item->GetDecal(d++))) - { - m_decals.Append(decal); - } + decals_node->AttachChildNode(new ON_XMLNode(decal->XML())); } - - m_decal_index = 0; - m_populated = true; } - if (m_decal_index >= m_decals.Count()) - return nullptr; - - return m_decals[m_decal_index++]; - } - -private: - ON_SimpleArray m_decals; - bool m_populated = false; -}; - -ON_DecalIterator::ON_DecalIterator(ONX_Model& model, const ON_ModelComponent* component) -{ - if (nullptr != component) - { - m_impl = new CImpl_PerComponent(model, *component); - } - else - { - m_impl = new CImpl_All(model); + SetRDKObjectInformation(*attr, root.String(), archive_3dm_version); } } - -ON_DecalIterator::~ON_DecalIterator() -{ - delete m_impl; - m_impl = nullptr; -} - -ON_Decal* ON_DecalIterator::Next(void) const -{ - return m_impl->Next(); -} diff --git a/opennurbs_decals.h b/opennurbs_decals.h index 823b734f..a4023176 100644 --- a/opennurbs_decals.h +++ b/opennurbs_decals.h @@ -138,25 +138,11 @@ public: // only used for looking decals up in the model. ON_UUID Id(void) const; -private: - class CImpl; - CImpl* m_impl; - friend class ON_DecalIterator; -}; - -class ON_CLASS ON_DecalIterator final -{ -public: - ON_DecalIterator(class ONX_Model& model, const ON_ModelComponent* component); - ~ON_DecalIterator(); - - // Returns a pointer to the next decal or null if there are no more. The returned pointer - // points to an object inside the ONX_Model. You should not store this pointer. - ON_Decal* Next(void) const; - - class CImpl; + // Get the decal XML. Intended for internal use only. + const ON_XMLNode& XML(void) const; private: + class CImpl; CImpl* m_impl; }; diff --git a/opennurbs_defines.cpp b/opennurbs_defines.cpp index 3e611a05..78554048 100644 --- a/opennurbs_defines.cpp +++ b/opennurbs_defines.cpp @@ -836,7 +836,7 @@ double ON::AngleUnitScale( ON::AngleUnitSystem us_to ) { - if (ON::AngleUnitSystem::Unset == us_from || ON::AngleUnitSystem::Unset == us_from) + if (ON::AngleUnitSystem::Unset == us_from || ON::AngleUnitSystem::Unset == us_to) return ON_DBL_QNAN; // the default cases are here to keep lint quiet @@ -869,6 +869,10 @@ double ON::AngleUnitScale( case ON::AngleUnitSystem::Gradians: scale = 400.0; break; + case ON::AngleUnitSystem::Unset: + case ON::AngleUnitSystem::None: + ON_ERROR("unit system conversion undefined"); + break; } break; @@ -894,6 +898,10 @@ double ON::AngleUnitScale( case ON::AngleUnitSystem::Gradians: scale = 400.0/ON_PI; break; + case ON::AngleUnitSystem::Unset: + case ON::AngleUnitSystem::None: + ON_ERROR("unit system conversion undefined"); + break; } break; @@ -919,6 +927,10 @@ double ON::AngleUnitScale( case ON::AngleUnitSystem::Gradians: scale = 10.0/9.0; break; + case ON::AngleUnitSystem::Unset: + case ON::AngleUnitSystem::None: + ON_ERROR("unit system conversion undefined"); + break; } break; @@ -944,6 +956,10 @@ double ON::AngleUnitScale( case ON::AngleUnitSystem::Gradians: scale = 1.0/54.0; break; + case ON::AngleUnitSystem::Unset: + case ON::AngleUnitSystem::None: + ON_ERROR("unit system conversion undefined"); + break; } break; @@ -969,6 +985,10 @@ double ON::AngleUnitScale( case ON::AngleUnitSystem::Gradians: scale = 1.0/(54.0*60.0); break; + case ON::AngleUnitSystem::Unset: + case ON::AngleUnitSystem::None: + ON_ERROR("unit system conversion undefined"); + break; } break; @@ -994,8 +1014,17 @@ double ON::AngleUnitScale( case ON::AngleUnitSystem::Gradians: scale = 1.0; break; + case ON::AngleUnitSystem::Unset: + case ON::AngleUnitSystem::None: + ON_ERROR("unit system conversion undefined"); + break; } break; + + case ON::AngleUnitSystem::Unset: + case ON::AngleUnitSystem::None: + ON_ERROR("unit system conversion undefined"); + break; } return scale; @@ -2257,7 +2286,10 @@ ON_INTERNAL_OBSOLETE::V5_horizontal_alignment ON_INTERNAL_OBSOLETE::V5Horizontal case ON::TextHorizontalAlignment::Right: halign = ON_INTERNAL_OBSOLETE::V5_horizontal_alignment::Right; break; - } + case ON::TextHorizontalAlignment::Auto: + halign = ON_INTERNAL_OBSOLETE::V5_horizontal_alignment::Left; + break; + } return halign; } diff --git a/opennurbs_dithering.cpp b/opennurbs_dithering.cpp index 710b434f..3294b831 100644 --- a/opennurbs_dithering.cpp +++ b/opennurbs_dithering.cpp @@ -101,7 +101,7 @@ void ON_Dithering::SetOn(bool b) ON_Dithering::Methods ON_Dithering::Method(void) const { - const auto s = m_impl->GetParameter(XMLPathDit(), ON_DITHERING_METHOD, L"").AsString(); + const ON_wString s = m_impl->GetParameter(XMLPathDit(), ON_DITHERING_METHOD, L"").AsString(); if (ON_DITHERING_FLOYD_STEINBERG == s) return Methods::FloydSteinberg; @@ -110,7 +110,7 @@ ON_Dithering::Methods ON_Dithering::Method(void) const void ON_Dithering::SetMethod(Methods m) { - const auto* wsz = ON_DITHERING_SIMPLE_NOISE; + const wchar_t* wsz = ON_DITHERING_SIMPLE_NOISE; if (Methods::FloydSteinberg == m) wsz = ON_DITHERING_FLOYD_STEINBERG; diff --git a/opennurbs_embedded_file.cpp b/opennurbs_embedded_file.cpp index e2a3acd4..1be077b4 100644 --- a/opennurbs_embedded_file.cpp +++ b/opennurbs_embedded_file.cpp @@ -91,13 +91,13 @@ bool ON_EmbeddedFile::CImpl::LoadFile(const wchar_t* filename) auto& d = m_data; // Open the file. - auto* pFile = ON_FileStream::Open(filename, L"rb"); + FILE* pFile = ON_FileStream::Open(filename, L"rb"); if (nullptr == pFile) return false; // Get the length of the file data. ON_FileStream::SeekFromEnd(pFile, 0); - const auto data_length = size_t(ON_FileStream::CurrentPosition(pFile)); + const size_t data_length = size_t(ON_FileStream::CurrentPosition(pFile)); ON_FileStream::SeekFromStart(pFile, 0); // Allocate a buffer for the file data. @@ -118,7 +118,7 @@ bool ON_EmbeddedFile::CImpl::SaveFile(const wchar_t* filename) const return false; // Not loaded. // Open the file for writing. - auto* pFile = ON_FileStream::Open(filename, L"wb"); + FILE* pFile = ON_FileStream::Open(filename, L"wb"); if (nullptr == pFile) return false; @@ -196,7 +196,7 @@ bool ON_EmbeddedFile::LoadFromFile(const wchar_t* filename) bool ON_EmbeddedFile::SaveToFile(const wchar_t* filename) const { - const auto file = ON_FileSystemPath::CleanPath(filename); + const ON_wString file = ON_FileSystemPath::CleanPath(filename); if (!m_impl->SaveFile(file)) return false; @@ -249,7 +249,7 @@ bool ON_EmbeddedFile::Read(ON_BinaryArchive& archive) // Read the compressed buffer and uncompress it into uncompressed_buffer. bool bFailedCRC = false; - const auto pos_before = archive.CurrentPosition(); + const ON__UINT64 pos_before = archive.CurrentPosition(); if (!archive.ReadCompressedBuffer(uncompressed_size, d.m_buffer.get(), &bFailedCRC) && !bFailedCRC) return false; diff --git a/opennurbs_extensions.cpp b/opennurbs_extensions.cpp index 9c04aa4d..12356b6f 100644 --- a/opennurbs_extensions.cpp +++ b/opennurbs_extensions.cpp @@ -284,14 +284,14 @@ public: enum class RenderContentKinds { Material, Environment, Texture }; -const ON_3dmObjectAttributes* GetComponentAttributes(const ON_ModelComponent& component) +ON_3dmObjectAttributes* GetComponentAttributes(const ON_ModelComponent& component) { // To have attributes, the component must be an ON_ModelGeometryComponent. const auto* mgc = ON_ModelGeometryComponent::Cast(&component); if (nullptr == mgc) return nullptr; // Wrong type of component. - return mgc->Attributes(nullptr); + return mgc->ExclusiveAttributes(); } class ONX_Model::Extension final @@ -301,7 +301,7 @@ public: ~Extension(); using EmbeddedFileMap = std::unordered_map; - + bool GetRDKDocumentXML(ON_wString& xml, bool embedded_files, int archive_3dm_version) const; ONX_Model_UserData* GetRDKDocumentUserData(int archive_3dm_version) const; void PopulateDefaultRDKDocumentXML(ON_XMLRootNode& root) const; @@ -324,13 +324,11 @@ public: ON_SafeFrame m_safe_frame; ON_GroundPlane m_ground_plane; ON_LinearWorkflow m_linear_workflow; + ON_InternalXMLImpl m_environment_impl; ON_Skylight m_skylight; - ON_CurrentEnvironment m_current_environment; ON_Sun m_sun; ON_Dithering m_dithering; ON_RenderChannels m_render_channels; - ON_DecalCollection m_decal_collection; - ON_MeshModifierCollection m_mesh_modifier_collection; ON__UINT64 m_model_content_version_number = 0; }; @@ -359,7 +357,7 @@ ON_XMLVariant ON_InternalXMLImpl::GetParameter_NoType(const wchar_t* path_to_nod ON_XMLVariant ON_InternalXMLImpl::InternalGetParameter(const wchar_t* path_to_node, const wchar_t* param_name, const wchar_t* default_type, const ON_XMLVariant& def) const { - const auto& node = NodeAt(path_to_node); + const ON_XMLNode& node = NodeAt(path_to_node); ON_XMLVariant value; ON_XMLParameters p(node); @@ -382,7 +380,7 @@ bool ON_InternalXMLImpl::SetParameter_NoType(const wchar_t* path_to_node, const bool ON_InternalXMLImpl::InternalSetParameter(const wchar_t* path_to_node, const wchar_t* param_name, bool write_type, const ON_XMLVariant& value) { - auto& node = NodeAt(path_to_node); + ON_XMLNode& node = NodeAt(path_to_node); ON_XMLParameters p(node); p.SetWriteTypeProperty(write_type); @@ -2986,7 +2984,7 @@ bool ONX_Model::Read(ON_BinaryArchive& archive, unsigned int table_filter, return false; // Having read the model data, populate the RDK components. - const auto archive_3dm_version = archive.Archive3dmVersion(); + const int archive_3dm_version = archive.Archive3dmVersion(); m_extension->PopulateRDKComponents(archive_3dm_version); return true; @@ -4854,8 +4852,8 @@ ONX_Model::Extension::Extension(ONX_Model& m) m_safe_frame(m_doc_node), m_ground_plane(m_doc_node), m_linear_workflow(m_doc_node), + m_environment_impl(&m_doc_node), m_skylight(m_doc_node), - m_current_environment(m_doc_node, m.m_settings.m_RenderSettings), m_sun(m_doc_node), m_dithering(m_doc_node), m_render_channels(m_doc_node) @@ -4917,10 +4915,10 @@ bool ONX_Model::Extension::GetRDKDocumentXML(ON_wString& xml, bool embedded_file // Gets the entire RDK document XML as a string in 'xml'. If 'embedded_files' is true, // ON_EmbeddedFile objects are created for each embedded file. - const auto* pUserData = GetRDKDocumentUserData(archive_3dm_version); + const ONX_Model_UserData* pUserData = GetRDKDocumentUserData(archive_3dm_version); if (nullptr != pUserData) { - auto* model = embedded_files ? &m_model : nullptr; + ONX_Model* model = embedded_files ? &m_model : nullptr; if (GetEntireRDKDocument(*pUserData, xml, model)) return true; } @@ -4959,16 +4957,16 @@ ON_XMLNode* ONX_Model::Extension::GetRenderContentSectionNode(ON_XMLNode& docNod bool ONX_Model::Extension::CreateRenderContentFromXML(ON_XMLNode& model_node, RenderContentKinds kind) { - const auto* rc_section_node = GetRenderContentSectionNode(model_node, kind); + const ON_XMLNode* rc_section_node = GetRenderContentSectionNode(model_node, kind); if (nullptr == rc_section_node) return false; auto it = rc_section_node->GetChildIterator(); - const auto* rc_node = it.GetNextChild(); + const ON_XMLNode* rc_node = it.GetNextChild(); while (nullptr != rc_node) { - auto* rc = NewRenderContentFromNode(*rc_node); + ON_RenderContent* rc = NewRenderContentFromNode(*rc_node); if (nullptr != rc) { const auto ref = m_model.AddModelComponent(*rc); @@ -4989,14 +4987,14 @@ bool ONX_Model::Extension::CreateRenderContentFromXML(ON_XMLNode& model_node, Re bool ONX_Model::Extension::CreateXMLFromRenderContent(ON_XMLNode& model_node, RenderContentKinds kind) const { - auto* rc_section_node = GetRenderContentSectionNode(model_node, kind); + ON_XMLNode* rc_section_node = GetRenderContentSectionNode(model_node, kind); if (nullptr == rc_section_node) return false; rc_section_node->RemoveAllChildren(); ONX_ModelComponentIterator it(m_model, ON_ModelComponent::Type::RenderContent); - auto* component = it.FirstComponent(); + const ON_ModelComponent* component = it.FirstComponent(); while (nullptr != component) { const auto* rc = ON_RenderContent::Cast(component); @@ -5016,17 +5014,17 @@ bool ONX_Model::Extension::CreateXMLFromRenderContent(ON_XMLNode& model_node, Re bool ONX_Model::Extension::CreatePostEffectsFromXML(ON_XMLNode& doc_root_node, ON_PostEffect::Types type) { - auto* pep_section_node = GetPostEffectSectionNode(doc_root_node, type); + ON_XMLNode* pep_section_node = GetPostEffectSectionNode(doc_root_node, type); if (nullptr == pep_section_node) return false; auto it = pep_section_node->GetChildIterator(); - auto* pPostEffectNode = it.GetNextChild(); + ON_XMLNode* pPostEffectNode = it.GetNextChild(); while (nullptr != pPostEffectNode) { ON_PostEffect pep(*pPostEffectNode, type); - const auto ref = m_model.AddModelComponent(pep); + const ON_ModelComponentReference ref = m_model.AddModelComponent(pep); auto* pep_in_model = ON_PostEffect::Cast(ref.ModelComponent()); if (nullptr != pep_in_model) { @@ -5041,18 +5039,18 @@ bool ONX_Model::Extension::CreatePostEffectsFromXML(ON_XMLNode& doc_root_node, O bool ONX_Model::Extension::CreateXMLFromPostEffects(ON_XMLNode& doc_root_node, ON_PostEffect::Types type) const { - auto* pep_section_node = GetPostEffectSectionNode(doc_root_node, type); + ON_XMLNode* pep_section_node = GetPostEffectSectionNode(doc_root_node, type); if (nullptr == pep_section_node) return false; ONX_ModelComponentIterator it(m_model, ON_ModelComponent::Type::PostEffect); - auto* pComponent = it.FirstComponent(); + const ON_ModelComponent* pComponent = it.FirstComponent(); while (nullptr != pComponent) { const auto* pep = ON_PostEffect::Cast(pComponent); if ((nullptr != pep) && (pep->Type() == type)) { - auto* pep_node = FindPostEffectNodeForId(*pep_section_node, pep->Id()); + ON_XMLNode* pep_node = FindPostEffectNodeForId(*pep_section_node, pep->Id()); if (nullptr != pep_node) { *pep_node = pep->XML(); @@ -5089,10 +5087,10 @@ bool ONX_Model::Extension::PopulateRDKComponents(int archive_3dm_version) CreatePostEffectsFromXML(m_doc_node, ON_PostEffect::Types::Late); // Create the decal collection. - m_decal_collection.CreateDecalsFromXML(m_model, archive_3dm_version); + CreateDecalsFromXML(m_model, archive_3dm_version); // Create the mesh modifiers. - m_mesh_modifier_collection.CreateMeshModifiersFromXML(m_model, archive_3dm_version); + CreateMeshModifiersFromXML(m_model, archive_3dm_version); return true; } @@ -5113,13 +5111,13 @@ bool ONX_Model::Extension::UpdateRDKUserData(int archive_3dm_version) CreateXMLFromPostEffects(m_doc_node, ON_PostEffect::Types::Late); // Convert the decal collection to fresh XML. - m_decal_collection.CreateXMLFromDecals(m_model, archive_3dm_version); + CreateXMLFromDecals(m_model, archive_3dm_version); // Convert the mesh modifier collection to fresh XML. - m_mesh_modifier_collection.CreateXMLFromMeshModifiers(m_model, archive_3dm_version); + CreateXMLFromMeshModifiers(m_model, archive_3dm_version); // Get the RDK document user data. - auto* pUserData = GetRDKDocumentUserData(archive_3dm_version); + ONX_Model_UserData* pUserData = GetRDKDocumentUserData(archive_3dm_version); if (nullptr == pUserData) return false; // Shouldn't happen because we were able to get the XML earlier. @@ -5146,9 +5144,90 @@ ON_LinearWorkflow& ONX_Model::LinearWorkflow(void) const return m_extension->m_linear_workflow; } -ON_CurrentEnvironment& ONX_Model::CurrentEnvironment(void) const +// This is inside the 'current content' section. +#define ON_RENDER_BACKGROUND_ENVIRONMENT L"environment" + +// These are inside the 'rendering' section. +#define ON_RENDER_CUSTOM_REFLECTIVE_ENVIRONMENT_ON L"custom-env-for-refl-and-refr-on" +#define ON_RENDER_CUSTOM_REFLECTIVE_ENVIRONMENT L"custom-env-for-refl-and-refr" + +// These are inside the 'sun' section. +#define ON_RENDER_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT_ON L"skylight-custom-environment-on" +#define ON_RENDER_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT L"skylight-custom-environment" + +static const wchar_t* XMLPathBack360(void) // Not used for 'override'. { - return m_extension->m_current_environment; + return ON_RDK_DOCUMENT ON_RDK_SLASH ON_RDK_CURRENT_CONTENT; +} + +static const wchar_t* XMLPathReflRefr(void) +{ + return ON_RDK_DOCUMENT ON_RDK_SLASH ON_RDK_SETTINGS ON_RDK_SLASH ON_RDK_RENDERING; +} + +static const wchar_t* XMLPathSkylight(void) +{ + return ON_RDK_DOCUMENT ON_RDK_SLASH ON_RDK_SETTINGS ON_RDK_SLASH ON_RDK_SUN; +} + +ON_UUID ONX_Model::BackgroundRenderEnvironment(void) const +{ + const wchar_t* s = ON_RENDER_BACKGROUND_ENVIRONMENT; + return m_extension->m_environment_impl.GetParameter_NoType(XMLPathBack360(), s, L"uuid", ON_nil_uuid).AsUuid(); +} + +void ONX_Model::SetBackgroundRenderEnvironment(const ON_UUID& id) +{ + const wchar_t* s = ON_RENDER_BACKGROUND_ENVIRONMENT; + m_extension->m_environment_impl.SetParameter_NoType(XMLPathBack360(), s, id); +} + +bool ONX_Model::SkylightingRenderEnvironmentOverride(void) const +{ + const wchar_t* s = ON_RENDER_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT_ON; + return m_extension->m_environment_impl.GetParameter(XMLPathSkylight(), s, false); +} + +void ONX_Model::SetSkylightingRenderEnvironmentOverride(bool on) +{ + const wchar_t* s = ON_RENDER_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT_ON; + m_extension->m_environment_impl.SetParameter(XMLPathSkylight(), s, on); +} + +ON_UUID ONX_Model::SkylightingRenderEnvironment(void) const +{ + const wchar_t* s = ON_RENDER_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT; + return m_extension->m_environment_impl.GetParameter_NoType(XMLPathSkylight(), s, L"uuid", ON_nil_uuid).AsUuid(); +} + +void ONX_Model::SetSkylightingRenderEnvironment(const ON_UUID& id) +{ + const wchar_t* s = ON_RENDER_SUN_SKYLIGHT_CUSTOM_ENVIRONMENT; + m_extension->m_environment_impl.SetParameter_NoType(XMLPathSkylight(), s, id); +} + +bool ONX_Model::ReflectionRenderEnvironmentOverride(void) const +{ + const wchar_t* s = ON_RENDER_CUSTOM_REFLECTIVE_ENVIRONMENT_ON; + return m_extension->m_environment_impl.GetParameter(XMLPathReflRefr(), s, false); +} + +void ONX_Model::SetReflectionRenderEnvironmentOverride(bool on) +{ + const wchar_t* s = ON_RENDER_CUSTOM_REFLECTIVE_ENVIRONMENT_ON; + m_extension->m_environment_impl.SetParameter(XMLPathReflRefr(), s, on); +} + +ON_UUID ONX_Model::ReflectionRenderEnvironment(void) const +{ + const wchar_t* s = ON_RENDER_CUSTOM_REFLECTIVE_ENVIRONMENT; + return m_extension->m_environment_impl.GetParameter_NoType(XMLPathReflRefr(), s, L"uuid", ON_nil_uuid).AsUuid(); +} + +void ONX_Model::SetReflectionRenderEnvironment(const ON_UUID& id) +{ + const wchar_t* s = ON_RENDER_CUSTOM_REFLECTIVE_ENVIRONMENT; + m_extension->m_environment_impl.SetParameter_NoType(XMLPathReflRefr(), s, id); } ON_Skylight& ONX_Model::Skylight(void) const @@ -5171,31 +5250,6 @@ ON_RenderChannels& ONX_Model::RenderChannels(void) const return m_extension->m_render_channels; } -ON_DecalCollection& GetDecalCollection(ONX_Model& model) -{ - return model.m_extension->m_decal_collection; -} - -ON_DecalIterator ONX_Model::GetDecalIterator(const ON_ModelComponent* component) -{ - return ON_DecalIterator(*this, component); -} - -ON_Decal* ONX_Model::AddDecal(const ON_ModelComponent& component) -{ - return m_extension->m_decal_collection.AddDecal(component); -} - -ON_Decal* ONX_Model::GetDecal(const ON_UUID& id) -{ - return m_extension->m_decal_collection.GetDecal(id); -} - -ON_MeshModifiers* ONX_Model::GetMeshModifiers(const ON_ModelComponent& component) -{ - return m_extension->m_mesh_modifier_collection.Find(component); -} - bool IsRDKDocumentInformation(const ONX_Model_UserData& docud) { return (0 == ON_UuidCompare(RdkPlugInId(), docud.m_uuid)) && (docud.m_goo.m_value >= 4) && (nullptr != docud.m_goo.m_goo); @@ -5208,8 +5262,8 @@ bool ONX_Model::IsRDKDocumentInformation(const ONX_Model_UserData& docud) static size_t ArchiveLengthUpToEmbeddedFiles(size_t utf8_length) { - // version utf8_length utf8_buf - const auto length = sizeof(ON__INT32) + sizeof(ON__INT32) + utf8_length; + // version utf8_length utf8_buf + const size_t length = sizeof(ON__INT32) + sizeof(ON__INT32) + utf8_length; ON_ASSERT(length <= INT_MAX); return length; @@ -5347,7 +5401,7 @@ bool ONX_Model::GetRDKEmbeddedFilePaths(const ONX_Model_UserData& docud, ON_Clas ON_Read3dmBufferArchive archive(docud.m_goo.m_value, docud.m_goo.m_goo, false, docud.m_usertable_3dm_version, docud.m_usertable_opennurbs_version); - const auto count = SeekArchiveToEmbeddedFiles(archive, docud.m_goo.m_value); + const int count = SeekArchiveToEmbeddedFiles(archive, docud.m_goo.m_value); if (!ReadEmbeddedFilePathsFromArchive(archive, count, paths)) return false; @@ -5361,7 +5415,7 @@ bool GetRDKEmbeddedFiles(const ONX_Model_UserData& docud, ON_ClassArrayId()); + pComponent = it.NextComponent(); } @@ -5494,7 +5549,7 @@ bool ONX_Model::Extension::GetEntireRDKDocument(const ONX_Model_UserData& docud, if (utf8_length <= 0) return false; - const auto length_so_far = ArchiveLengthUpToEmbeddedFiles(utf8_length); + const size_t length_so_far = ArchiveLengthUpToEmbeddedFiles(utf8_length); if (length_so_far > size_t(docud.m_goo.m_value)) return false; // Sanity check. @@ -5563,7 +5618,7 @@ bool ONX_Model::Extension::SetRDKDocumentInformation(const wchar_t* xml, ONX_Mod { // BEGIN UTF8 auto utf8 = std::unique_ptr(new char[utf8_length]); - auto* utf8_buf = utf8.get(); + char* utf8_buf = utf8.get(); ON_ConvertWideCharToUTF8(false, xml, -1, utf8_buf, utf8_length, &error_status, 0, 0, 0); @@ -5586,7 +5641,7 @@ bool ONX_Model::Extension::SetRDKDocumentInformation(const wchar_t* xml, ONX_Mod // Write the embedded files to the archive. ONX_ModelComponentIterator it(m_model, ON_ModelComponent::Type::EmbeddedFile); - auto* pComponent = it.FirstComponent(); + const ON_ModelComponent* pComponent = it.FirstComponent(); while (nullptr != pComponent) { const auto* embedded_file = ON_EmbeddedFile::Cast(pComponent); @@ -5613,11 +5668,6 @@ bool ONX_Model::Extension::SetRDKDocumentInformation(const wchar_t* xml, ONX_Mod // Object user data -static const ON_UUID uuid_displacement_plug_in // The displacement plug-in implements all 5 mesh modifiers. -{ - 0xF293DE5C, 0xD1FF, 0x467A, { 0x9B, 0xD1, 0xCA, 0xC8, 0xEC, 0x4B, 0x2E, 0x6B } -}; - static ON_UserData* RDKObjectUserDataHelper(const ON_UserData* objectud) { if (nullptr == objectud) @@ -5636,7 +5686,7 @@ static ON_UserData* RDKObjectUserDataHelper(const ON_UserData* objectud) static bool IsMeshModifierObjectUserData(ON_UserData& objectud) { - if (0 == ON_UuidCompare(objectud.m_application_uuid, uuid_displacement_plug_in)) + if (0 == ON_UuidCompare(objectud.m_application_uuid, ON_MeshModifier::PlugInId())) return true; // User data from Displacement plug-in. return false; @@ -5657,13 +5707,13 @@ bool CreateArchiveBufferFromXML(const ON_wString& xml, ON_Buffer& buf, int archi if (!archive.WriteInt(version)) return false; - const auto* wsz = static_cast(xml); + const wchar_t* wsz = static_cast(xml); unsigned int error_status = 0; - const auto num_chars = ON_ConvertWideCharToUTF8(false, wsz, -1, nullptr, 0, &error_status, 0, 0, nullptr); + const int num_chars = ON_ConvertWideCharToUTF8(false, wsz, -1, nullptr, 0, &error_status, 0, 0, nullptr); auto p = std::unique_ptr(new char[size_t(num_chars) + 1]); - auto* pBuffer = p.get(); + char* pBuffer = p.get(); ON_ConvertWideCharToUTF8(false, wsz, -1, pBuffer, num_chars + 1, &error_status, 0, 0, nullptr); if (0 != error_status) @@ -5714,7 +5764,7 @@ bool SetRDKObjectInformation(ON_Object& object, const ON_wString& xml, int archi // Try to find existing user data. ON_UserData* rdk_ud = nullptr; - for (auto* ud = object.FirstUserData(); (nullptr != ud) && (nullptr == rdk_ud); ud = ud->Next()) + for (ON_UserData* ud = object.FirstUserData(); (nullptr != ud) && (nullptr == rdk_ud); ud = ud->Next()) { rdk_ud = RDKObjectUserDataHelper(ud); } @@ -5768,11 +5818,11 @@ bool GetRDKObjectInformation(const ON_Object& object, ON_wString& xml, int archi const auto sizeof_buffer = buf.Size(); auto p = std::unique_ptr(new ON__UINT8[sizeof_buffer]); - auto* buffer = p.get(); + ON__UINT8* buffer = p.get(); buf.SeekFromStart(0); buf.Read(sizeof_buffer, buffer); - const auto archive_opennurbs_version_number = ON::Version(); + const unsigned int archive_opennurbs_version_number = ON::Version(); ON_Read3dmBufferArchive archive(sizeof_buffer, buffer, false, archive_3dm_version, archive_opennurbs_version_number); int version = 0; @@ -5838,10 +5888,10 @@ static bool GetMeshModifierUserDataXML(ON_UserData& ud, ON_wString& xml, int arc ON_BinaryArchiveBuffer arc(ON::archive_mode::write, &buf); ud.Write(arc); - const auto sizeof_buffer = buf.Size(); + const ON__UINT64 sizeof_buffer = buf.Size(); auto p = std::unique_ptr(new ON__UINT8[sizeof_buffer]); - auto* buffer = p.get(); + ON__UINT8* buffer = p.get(); buf.SeekFromStart(0); buf.Read(sizeof_buffer, buffer); @@ -5915,13 +5965,13 @@ bool GetMeshModifierObjectInformation(const ON_Object& object, ON_wString& xml, { xml = L""; - // The mesh modifiers are stored in separate user data items. We must get each one's XML - // and combine it into a single XML node containing the entire information for all + // The mesh modifiers are stored in separate user data items. We must get each one's + // XML and combine it into a single XML node containing the entire information for all // mesh modifiers on this object. ON_XMLRootNode entire; - auto* ud = object.FirstUserData(); + ON_UserData* ud = object.FirstUserData(); while (nullptr != ud) { if (IsMeshModifierObjectUserData(*ud)) @@ -5931,7 +5981,7 @@ bool GetMeshModifierObjectInformation(const ON_Object& object, ON_wString& xml, ON_XMLRootNode root; root.ReadFromStream(ud_xml); - auto* mm_node = root.FirstChild(); + ON_XMLNode* mm_node = root.FirstChild(); if (nullptr != mm_node) { root.DetachChild(*mm_node); @@ -5953,30 +6003,58 @@ bool GetMeshModifierObjectInformation(const ON_Object& object, ON_wString& xml, static ON_UserData* GetMeshModifierUserData(ON_Object& object, const ON_UUID& uuid_mm) { - auto* ud = object.FirstUserData(); - while (nullptr != ud) + ON_UserData* existing_ud = object.FirstUserData(); + while (nullptr != existing_ud) { - if (ud->m_userdata_uuid == uuid_mm) - return ud; + if (existing_ud->m_userdata_uuid == uuid_mm) + return existing_ud; - ud = ud->Next(); + existing_ud = existing_ud->Next(); } // Not found so create it. - return nullptr; // TODO: ////////////////////////////////////////////////////////// + ON_XMLUserData* new_ud = nullptr; + + if (uuid_mm == ON_DisplacementUserData::Uuid()) new_ud = new ON_DisplacementUserData; + else if (uuid_mm == ON_EdgeSofteningUserData::Uuid()) new_ud = new ON_EdgeSofteningUserData; + else if (uuid_mm == ON_ThickeningUserData::Uuid()) new_ud = new ON_ThickeningUserData; + else if (uuid_mm == ON_CurvePipingUserData::Uuid()) new_ud = new ON_CurvePipingUserData; + else if (uuid_mm == ON_ShutLiningUserData::Uuid()) new_ud = new ON_ShutLiningUserData; + else ON_ASSERT(false); + + if (nullptr != new_ud) + { + new_ud->SetToDefaults(); // This doesn't work because the XML gets overwritten by the cached XML. + // In fact, having cached XML in this and decals is the reason why the systems are wrong. + // I'm about to fix the decals to not have cached XML and directly use the user data. After + // that I'll do the same for mesh modifiers. Then, this should work because there is no longer + // an XML cache to overwrite the new defaults in the user data's XML. + + if (!object.AttachUserData(new_ud)) + { + delete new_ud; + new_ud = nullptr; + } + } + + return new_ud; } -void SetMeshModifierObjectInformation(ON_Object& object, const ON_UUID& uuid_mm, const ON_MeshModifier& mm, int archive_3dm_version) +void SetMeshModifierObjectInformation(ON_Object& object, const ON_MeshModifier* mm, const ON_XMLNode& node, int archive_3dm_version, const wchar_t* mm_node_name) { - ON_XMLRootNode r1; - r1.ReadFromStream(mm.XML()); // Does not include node. + if (nullptr == mm) + return; // Don't create user data for non-existent mesh modifiers. - ON_XMLRootNode r2; - r2.AttachChildNode(new ON_XMLNode(r1)); // Includes node. + const ON_XMLNode* mm_node = node.GetNamedChild(mm_node_name); + if (nullptr == mm_node) + return; // Don't create user data for non-existent mesh modifier. - auto* ud = GetMeshModifierUserData(object, uuid_mm); + ON_XMLRootNode root; + root.AttachChildNode(new ON_XMLNode(*mm_node)); + + ON_UserData* ud = GetMeshModifierUserData(object, mm->Uuid()); if (nullptr != ud) { - SetXMLToUserData(r2.String(), *ud, archive_3dm_version); + SetXMLToUserData(root.String(), *ud, archive_3dm_version); } } diff --git a/opennurbs_extensions.h b/opennurbs_extensions.h index b61874fb..3d8579db 100644 --- a/opennurbs_extensions.h +++ b/opennurbs_extensions.h @@ -1599,8 +1599,21 @@ public: // Linear Workflow. ON_LinearWorkflow& LinearWorkflow(void) const; - // Current Environment. - ON_CurrentEnvironment& CurrentEnvironment(void) const; + // Background rendering environment. + ON_UUID BackgroundRenderEnvironment(void) const; + void SetBackgroundRenderEnvironment(const ON_UUID& id); + + // Skylighting rendering environment. + bool SkylightingRenderEnvironmentOverride(void) const; + void SetSkylightingRenderEnvironmentOverride(bool on); + ON_UUID SkylightingRenderEnvironment(void) const; + void SetSkylightingRenderEnvironment(const ON_UUID& id); + + // Reflection / refraction rendering environment. + bool ReflectionRenderEnvironmentOverride(void) const; + void SetReflectionRenderEnvironmentOverride(bool on); + ON_UUID ReflectionRenderEnvironment(void) const; + void SetReflectionRenderEnvironment(const ON_UUID& id); // Skylight. ON_Skylight& Skylight(void) const; @@ -1614,27 +1627,6 @@ public: // Render Channels. ON_RenderChannels& RenderChannels(void) const; - // - If 'component' is not null, this gets decals stored on that component. Generally, only model - // components of type ModelGeometry have decals on them. - // If there are no decals on the component, the iterator will be empty and return null if Next() is called. - // - // - If 'component' is null, then this gets all decals from all model components. - // - // Returns a decal iterator which allows access to the decals. - ON_DecalIterator GetDecalIterator(const ON_ModelComponent* component); - - // Adds a new decal to a particular component. - // Returns a pointer to the decal if successful, or null on failure. - ON_Decal* AddDecal(const ON_ModelComponent& component); - - // Gets a decal by its id. - // Returns a pointer to the decal if successful, or null on failure. - ON_Decal* GetDecal(const ON_UUID& id); - - // Get mesh modifiers stored on a particular component. Generally, only model components of type ModelGeometry - // have mesh modifiers on them. Returns an object which provides access to the various mesh modifiers. - ON_MeshModifiers* GetMeshModifiers(const ON_ModelComponent& component); - ON_DEPRECATED_MSG("This function is deprecated.") static bool IsRDKDocumentInformation(const ONX_Model_UserData& docud); diff --git a/opennurbs_font.cpp b/opennurbs_font.cpp index e0e7b50c..04f3adea 100644 --- a/opennurbs_font.cpp +++ b/opennurbs_font.cpp @@ -9683,7 +9683,7 @@ bool ON_Font::IsValid(ON_TextLog* text_log) const void ON_Font::Dump(ON_TextLog& dump) const { - const bool bTextHash = dump.IsTextHash();; + const bool bTextHash = dump.IsTextHash(); ON_wString s; diff --git a/opennurbs_internal_defines.h b/opennurbs_internal_defines.h index cafe1099..4cb273b5 100644 --- a/opennurbs_internal_defines.h +++ b/opennurbs_internal_defines.h @@ -56,7 +56,7 @@ ON__INT64 Integerize(double dirty); void SetModel(const class ON_RenderContent&, ONX_Model&); void SetModel(const class ON_PostEffect&, ONX_Model&); -const ON_3dmObjectAttributes* GetComponentAttributes(const ON_ModelComponent& component); +ON_3dmObjectAttributes* GetComponentAttributes(const ON_ModelComponent& component); ON_RenderContent* NewRenderContentFromNode(const class ON_XMLNode& node); ON_PostEffect* NewPostEffectFromNode(ON_XMLNode& node); void SetRenderContentNodeRecursive(const ON_RenderContent& rc, ON_XMLNode& node); @@ -65,8 +65,12 @@ ON_XMLNode* FindPostEffectNodeForId(const ON_XMLNode& sectionNode, const ON_UUID bool GetRDKObjectInformation(const ON_Object& object, ON_wString& xml, int archive_3dm_version); bool SetRDKObjectInformation(ON_Object& object, const ON_wString& xml, int archive_3dm_version); bool GetRDKEmbeddedFiles(const ONX_Model_UserData& docud, ON_ClassArray& paths, ON_SimpleArray& embedded_files_as_buffers, ON_SimpleArray& buffer_sizes); +void CreateDecalsFromXML(const ONX_Model& model, int archive_3dm_version); +void CreateXMLFromDecals(const ONX_Model& model, int archive_3dm_version); +void CreateMeshModifiersFromXML(const ONX_Model& model, int archive_3dm_version); +void CreateXMLFromMeshModifiers(const ONX_Model& model, int archive_3dm_version); bool GetMeshModifierObjectInformation(const ON_Object& object, ON_wString& xml, int archive_3dm_version); -void SetMeshModifierObjectInformation(ON_Object& object, const ON_UUID& uuid_mm, const ON_MeshModifier& mm, int archive_3dm_version); +void SetMeshModifierObjectInformation(ON_Object& object, const ON_MeshModifier* mm, const ON_XMLNode& node, int archive_3dm_version, const wchar_t* mm_node_name); bool IsRDKDocumentInformation(const ONX_Model_UserData& docud); template inline T Lerp(float t, const T& l, const T& h) { return l + T(t) * (h - l); } @@ -102,65 +106,22 @@ public: class ON_DecalCollection final { public: + ON_DecalCollection() { } + ON_DecalCollection(const ON_DecalCollection& dc) = delete; ~ON_DecalCollection(); - class Item final - { - public: - Item(const ON_UUID& component_id); - Item(const Item&) = delete; - ~Item(); + const ON_DecalCollection& operator = (const ON_DecalCollection& dc); - const Item& operator = (const Item&) = delete; - - ON_wString DecalsXML(void) const; // Returns node. - bool SetXML(const wchar_t* xml); // Sets from node. - bool SetDecalsXML(const ON_XMLNode& decals_node); // Sets from node. - - ON_UUID ComponentId(void) const { return m_component_id; } - - ON_Decal* GetDecal(int index) const; - - ON_Decal* GetDecal(const ON_UUID& id) const; - - void DeleteAllDecals(void); - - private: - ON_UUID m_component_id; - ON_XMLNode m_decals_node; - ON_SimpleArray m_decals; - }; - - // Create the decals from all model components that have decal user data. - void CreateDecalsFromXML(const ONX_Model& model, int archive_3dm_version); - - // Convert the decals back to XML for all model components that have decal user data. - void CreateXMLFromDecals(const ONX_Model& model, int archive_3dm_version); - - // Find the item index for a certain component. - int FindItemIndex(const ON_UUID& component_id) const; - - // Find the item for a certain component. - Item* FindItem(const ON_UUID& component_id) const; - - // Get the item at an index. - Item* ItemAt(int index) const; - - // Get the number of items. - int ItemCount(void) const; - - // Add a new decal to a certain component. - ON_Decal* AddDecal(const ON_ModelComponent& component); - - // Get a decal by its id. - ON_Decal* GetDecal(const ON_UUID& id); + void DeleteAllDecals(void); + void Populate(const ON_XMLRootNode& node); + ON_Decal* AddDecal(void); + const ON_SimpleArray& GetDecalArray(void) const { return m_decals; } + static bool NodeContainsDecals(const ON_XMLRootNode& node); private: - ON_SimpleArray m_items; + ON_SimpleArray m_decals; }; -ON_DecalCollection& GetDecalCollection(ONX_Model& model); - template inline void hash_combine(size_t& seed, const T& v) { std::hash hasher; @@ -186,24 +147,6 @@ public: } }; -class ON_MeshModifierCollection final -{ -public: - ~ON_MeshModifierCollection(); - - // Find the mesh modifiers for a particular model component. - ON_MeshModifiers* Find(const ON_ModelComponent& component); - - // Create the mesh modifiers from all model components that have mesh modifier user data. - bool CreateMeshModifiersFromXML(const ONX_Model& model, int archive_3dm_version); - - // Convert the mesh modifiers back to XML for all model components that have mesh modifier user data. - bool CreateXMLFromMeshModifiers(const ONX_Model& model, int archive_3dm_version); - -private: - std::unordered_map m_map; -}; - //-------------------------------------------------------------------------------------------------- class ON_INTERNAL_OBSOLETE diff --git a/opennurbs_light.cpp b/opennurbs_light.cpp index d7f6c76f..9d4f9d4e 100644 --- a/opennurbs_light.cpp +++ b/opennurbs_light.cpp @@ -548,7 +548,7 @@ const ON_wString& ON_Light::LightName() const void ON_Light::SetAttenuation(double a,double b,double c) { - m_attenuation = ON_3dVector(a,b,c);; + m_attenuation = ON_3dVector(a,b,c); } void ON_Light::SetAttenuation(const ON_3dVector& att ) @@ -758,7 +758,7 @@ void ON_Light::SetDiffuse( ON_Color c ) void ON_Light::SetSpecular( ON_Color c ) { - m_specular = c;; + m_specular = c; } ON_Color ON_Light::Ambient() const diff --git a/opennurbs_linear_workflow.cpp b/opennurbs_linear_workflow.cpp index c3bec5fd..d6435022 100644 --- a/opennurbs_linear_workflow.cpp +++ b/opennurbs_linear_workflow.cpp @@ -157,10 +157,10 @@ void ON_LinearWorkflow::ApplyPreProcessGamma(ON_4fColor& col, bool for_texture) if (!check) return; - const auto gamma = PreProcessGamma(); + const float gamma = PreProcessGamma(); if (!IsFloatEqual(gamma, 1.0f)) { - auto* f = col.FloatArray(); + float* f = col.FloatArray(); ON_ASSERT((f[0] >= 0.0) && (f[1] >= 0.0) && (f[2] >= 0.0)); diff --git a/opennurbs_material.cpp b/opennurbs_material.cpp index 6c6d69a6..2bc3c7f9 100644 --- a/opennurbs_material.cpp +++ b/opennurbs_material.cpp @@ -3840,6 +3840,12 @@ ON__UINT32 ON_TextureMapping::MappingCRC() const } } } + else + { + // Jussi, Aug 18 2022, RH-69752: Surface mapping uvw transform has changed. + // Changing crc makes sure existing models will show the correct mapping. + crc32++; + } crc32 = ON_CRC32(crc32,sizeof(m_uvw), &m_uvw); return crc32; @@ -4000,21 +4006,8 @@ bool GetSPTCHelper( const ON_Interval tex_vdom = mesh.m_packed_tex_domain[1]; for ( i = 0; i < vcnt; i++) { - //ALB 2011.01.14 - //Added support for m_uvw in packed textures. Even though this conceptually makes - //very little sense, it's one of the most requested features for the texture mapping - //system, so I grudgingly add it. - if (bHaveUVWXform) - { - const ON_2dPoint si = mapping.m_uvw*S[i]; - u = si.x; - v = si.y; - } - else - { - u = S[i].x; - v = S[i].y; - } + u = S[i].x; + v = S[i].y; // (u, v) = known surface parameter if ( mesh.m_packed_tex_rotate ) @@ -4034,6 +4027,14 @@ bool GetSPTCHelper( u = tex_udom.ParameterAt(a); v = tex_vdom.ParameterAt(b); + // Jussi, Aug 18 2022, RH-69752: Apply uvw transform in texture space + if (bHaveUVWXform) + { + const ON_2dPoint si = mapping.m_uvw * ON_2dPoint(u, v); + u = si.x; + v = si.y; + } + tc[0] = (float)u; tc[1] = (float)v; tc += tc_stride; @@ -5464,7 +5465,7 @@ void AdjustMeshPeriodicTextureCoordinatesHelper( // map and clamp the tcs that hang over. If the mesh // has edges near the texture seam, the picture will // still look ok. - float f0=0.0f, f1=0.0f, twopitc = (float)two_pi_tc;; + float f0=0.0f, f1=0.0f, twopitc = (float)two_pi_tc; //int f0cnt=0, f1cnt=0; if ( 1 == ftc.quad[0] ) f0 += ftc.Tx[0]; else if ( 4 == ftc.quad[0] ) f1 += twopitc-ftc.Tx[0]; if ( 1 == ftc.quad[1] ) f0 += ftc.Tx[1]; else if ( 4 == ftc.quad[1] ) f1 += twopitc-ftc.Tx[1]; diff --git a/opennurbs_mesh_modifiers.cpp b/opennurbs_mesh_modifiers.cpp index 64b24ca5..3522443e 100644 --- a/opennurbs_mesh_modifiers.cpp +++ b/opennurbs_mesh_modifiers.cpp @@ -22,11 +22,22 @@ #error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs #endif +ON_UUID ON_MeshModifier::PlugInId(void) // Static. +{ + static const ON_UUID uuid = + { + // {f293de5c-d1ff-467a-9bd1-cac8ec4b2e6b} + 0xf293de5c, 0xd1ff, 0x467a, {0x9b, 0xd1, 0xca, 0xc8, 0xec, 0x4b, 0x2e, 0x6b} + }; + + return uuid; +} + class ON_MeshModifier::CImpl : public ON_InternalXMLImpl { public: CImpl() { } - CImpl(ON_XMLNode& n) : ON_InternalXMLImpl(&n) { } + CImpl(const ON_XMLNode& n) { Node() = n; } }; ON_MeshModifier::ON_MeshModifier() @@ -34,9 +45,9 @@ ON_MeshModifier::ON_MeshModifier() m_impl = new CImpl; } -ON_MeshModifier::ON_MeshModifier(ON_XMLNode& model_node) +ON_MeshModifier::ON_MeshModifier(const ON_XMLNode& node) { - m_impl = new CImpl(model_node); + m_impl = new CImpl(node); } ON_MeshModifier::~ON_MeshModifier() @@ -45,10 +56,15 @@ ON_MeshModifier::~ON_MeshModifier() m_impl = nullptr; } -ON_wString ON_MeshModifier::XML(void) const +ON_XMLNode* ON_MeshModifier::AddChildXML(ON_XMLRootNode& root) const { - // The XML does not include the node. It's the actual mesh modifier node. - return m_impl->Node().String(); + ON_XMLNode* mm_node = root.AttachChildNode(new ON_XMLNode(L"")); + if (nullptr != mm_node) + { + *mm_node = m_impl->Node(); + } + + return mm_node; } //////////////////////////////////////////////////////////////// @@ -57,30 +73,126 @@ ON_wString ON_MeshModifier::XML(void) const // //////////////////////////////////////////////////////////////// -#define ON_DISPLACEMENT_ROOT L"new-displacement-object-data" - #define ON_DISPLACEMENT_ON L"on" - #define ON_DISPLACEMENT_CHANNEL L"channel" - #define ON_DISPLACEMENT_BLACK_POINT L"black-point" - #define ON_DISPLACEMENT_WHITE_POINT L"white-point" - #define ON_DISPLACEMENT_SWEEP_PITCH L"sweep-pitch" - #define ON_DISPLACEMENT_REFINE_STEPS L"refine-steps" - #define ON_DISPLACEMENT_REFINE_SENSITIVITY L"refine-sensitivity" - #define ON_DISPLACEMENT_TEXTURE L"texture" - #define ON_DISPLACEMENT_FACE_COUNT_LIMIT_ENABLED L"face-count-limit-enabled" - #define ON_DISPLACEMENT_FACE_COUNT_LIMIT L"face-count-limit" - #define ON_DISPLACEMENT_POST_WELD_ANGLE L"post-weld-angle" - #define ON_DISPLACEMENT_MESH_MEMORY_LIMIT L"mesh-memory-limit" - #define ON_DISPLACEMENT_FAIRING_ENABLED L"fairing-enabled" - #define ON_DISPLACEMENT_FAIRING_AMOUNT L"fairing-amount" - #define ON_DISPLACEMENT_SWEEP_RES_FORMULA L"sweep-res-formula" - #define ON_DISPLACEMENT_SUB_OBJECT_COUNT L"sub-object-count" - #define ON_DISPLACEMENT_SUB L"sub" - #define ON_DISPLACEMENT_SUB_INDEX L"sub-index" - #define ON_DISPLACEMENT_SUB_ON L"sub-on" - #define ON_DISPLACEMENT_SUB_TEXTURE L"sub-texture" - #define ON_DISPLACEMENT_SUB_CHANNEL L"sub-channel" - #define ON_DISPLACEMENT_SUB_BLACK_POINT L"sub-black-point" - #define ON_DISPLACEMENT_SUB_WHITE_POINT L"sub-white-point" +ON_OBJECT_IMPLEMENT(ON_DisplacementUserData, ON_UserData, "B8C04604-B4EF-43b7-8C26-1AFB8F1C54EB"); + +ON_UUID ON_DisplacementUserData::Uuid(void) +{ + static const ON_UUID uuid = { 0x8224a7c4, 0x5590, 0x4ac4, { 0xa3, 0x2c, 0xde, 0x85, 0xdc, 0x2f, 0xfd, 0xae } }; + return uuid; +} + +ON_DisplacementUserData::ON_DisplacementUserData() +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + SetToDefaults(); +} + +ON_DisplacementUserData::ON_DisplacementUserData(const ON_DisplacementUserData& ud) + : + ON_XMLUserData(ud) // CRITICAL - Be sure to call base class. +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + // DO NOT SET OTHER ON_UserData fields + // In particular, do not set m_userdata_copycount + *this = ud; +} + +const ON_DisplacementUserData& ON_DisplacementUserData::operator = (const ON_DisplacementUserData& ud) +{ + if (this != &ud) + ON_XMLUserData::operator = (ud); + + return *this; +} + +bool ON_DisplacementUserData::GetDescription(ON_wString& s) +{ + s = L"Displacement object data"; + return true; +} + +void ON_DisplacementUserData::SetToDefaults(void) const +{ + auto& ud = const_cast(*this); + ud.Clear(); + + ON_Displacement::Defaults d; + + ON_XMLNode* root = ud.XMLRootForWrite().AttachChildNode(new ON_XMLNode(ON_DISPLACEMENT_ROOT)); + + ON_XMLParameters p(*root); + p.SetParam(ON_DISPLACEMENT_ON, false); + p.SetParam(ON_DISPLACEMENT_CHANNEL, d.ChannelNumber()); + p.SetParam(ON_DISPLACEMENT_BLACK_POINT, d.BlackPoint()); + p.SetParam(ON_DISPLACEMENT_WHITE_POINT, d.WhitePoint()); + p.SetParam(ON_DISPLACEMENT_SWEEP_PITCH, d.SweepPitch()); + p.SetParam(ON_DISPLACEMENT_REFINE_STEPS, d.RefineStepCount()); + p.SetParam(ON_DISPLACEMENT_REFINE_SENSITIVITY, d.RefineSensitivity()); + p.SetParam(ON_DISPLACEMENT_TEXTURE, ON_nil_uuid); + p.SetParam(ON_DISPLACEMENT_FACE_COUNT_LIMIT_ENABLED, false); + p.SetParam(ON_DISPLACEMENT_FACE_COUNT_LIMIT, d.FaceLimit()); + p.SetParam(ON_DISPLACEMENT_POST_WELD_ANGLE, d.PostWeldAngle()); + p.SetParam(ON_DISPLACEMENT_MESH_MEMORY_LIMIT, d.MeshMemoryLimit()); + p.SetParam(ON_DISPLACEMENT_FAIRING_ENABLED, false); + p.SetParam(ON_DISPLACEMENT_FAIRING_AMOUNT, d.FairingAmount()); + p.SetParam(ON_DISPLACEMENT_SUB_OBJECT_COUNT, 0); + p.SetParam(ON_DISPLACEMENT_SWEEP_RES_FORMULA, int(d.SweepResolutionFormula())); + + ON_XMLNode* sub_node = new ON_XMLNode(ON_DISPLACEMENT_SUB); + root->AttachChildNode(sub_node); + + ON_XMLParameters psub(*sub_node); + psub.SetParam(ON_DISPLACEMENT_SUB_INDEX, -1); + psub.SetParam(ON_DISPLACEMENT_SUB_ON, false); + psub.SetParam(ON_DISPLACEMENT_SUB_TEXTURE, ON_nil_uuid); + psub.SetParam(ON_DISPLACEMENT_SUB_CHANNEL, d.ChannelNumber()); + psub.SetParam(ON_DISPLACEMENT_SUB_BLACK_POINT, d.BlackPoint()); + psub.SetParam(ON_DISPLACEMENT_SUB_WHITE_POINT, d.WhitePoint()); +} + +void ON_DisplacementUserData::ReportVersionError(void) const +{ + //RhinoMessageBox(L"Version error", L"Displacement", MB_OK | MB_ICONERROR); +} + +bool ON_DisplacementUserData::Transform(const ON_Xform& xform) +{ +// if (nullptr != g_DisplacementUserDataTransformCallback) +// { +// (*g_DisplacementUserDataTransformCallback)(*this, xform); +// } + + return ON_XMLUserData::Transform(xform); +} + +bool ON_DisplacementUserData::Read(ON_BinaryArchive& archive) +{ + if (!ON_XMLUserData::Read(archive)) + return false; + + const int archive3dmVersion = archive.Archive3dmVersion(); + if (archive3dmVersion < 60) + { + ON_XMLNode* root = XMLRootForWrite().GetNamedChild(ON_DISPLACEMENT_ROOT); + if (root != nullptr) + { + ON_XMLParameters p(*root); + ON_XMLVariant v; + if (!p.GetParam(ON_DISPLACEMENT_SWEEP_RES_FORMULA, v)) + { + p.SetParam(ON_DISPLACEMENT_SWEEP_RES_FORMULA, 1); + } + } + } + + return true; +} class ON_Displacement::CImplDSP { @@ -88,20 +200,37 @@ public: ON_SimpleArray m_subs; }; -ON_Displacement::ON_Displacement(ON_XMLNode& model_node) +ON_Displacement::ON_Displacement() : - ON_MeshModifier(model_node) + ON_MeshModifier(ON_XMLNode(ON_DISPLACEMENT_ROOT)) +{ + m_impl_dsp = new CImplDSP; +} + +ON_Displacement::ON_Displacement(const ON_XMLNode& dsp_node) { m_impl_dsp = new CImplDSP; - auto it = model_node.GetChildIterator(); - while (auto* child_node = it.GetNextChild()) + // Iterate over the displacement node looking at each child node's name. If the child + // node is a sub-item node, create a sub-item object to hold the sub-item XML. Otherwise add + // a copy of the child node to a new displacement node. + ON_XMLNode new_dsp_node(dsp_node.TagName()); + + auto it = dsp_node.GetChildIterator(); + while (ON_XMLNode* child_node = it.GetNextChild()) { if (ON_DISPLACEMENT_SUB == child_node->TagName()) { m_impl_dsp->m_subs.Append(new SubItem(*child_node)); } + else + { + new_dsp_node.AttachChildNode(new ON_XMLNode(*child_node)); + } } + + // Copy the new displacement node to our node. It only contains displacement XML with no sub-item nodes. + m_impl->Node() = new_dsp_node; } ON_Displacement::ON_Displacement(const ON_Displacement& dsp) @@ -168,6 +297,23 @@ bool ON_Displacement::operator != (const ON_Displacement& dsp) const return !(operator == (dsp)); } +ON_XMLNode* ON_Displacement::AddChildXML(ON_XMLRootNode& root) const +{ + ON_XMLNode* dsp_node = ON_MeshModifier::AddChildXML(root); + if (nullptr != dsp_node) + { + auto it = GetSubItemIterator(); + SubItem* sub_item = nullptr; + while (nullptr != (sub_item = it.Next())) + { + ON_XMLNode* sub_node = dsp_node->AttachChildNode(new ON_XMLNode(L"")); + sub_item->ToXML(*sub_node); + } + } + + return dsp_node; +} + bool ON_Displacement::On(void) const { return m_impl->GetParameter(ON_DISPLACEMENT_ON, false).AsBool(); @@ -311,7 +457,7 @@ void ON_Displacement::SetRefineSensitivity(double s) ON_Displacement::SweepResolutionFormulas ON_Displacement::SweepResolutionFormula(void) const { const auto def = SweepResolutionFormulas::Default; - const auto v = m_impl->GetParameter(ON_DISPLACEMENT_SWEEP_RES_FORMULA, int(def)).AsInteger(); + const int v = m_impl->GetParameter(ON_DISPLACEMENT_SWEEP_RES_FORMULA, int(def)).AsInteger(); return SweepResolutionFormulas(v); } @@ -327,8 +473,8 @@ ON_Displacement::SubItemIterator ON_Displacement::GetSubItemIterator(void) const ON_Displacement::SubItem& ON_Displacement::AddSubItem(void) { - auto* sub_node = m_impl->Node().AttachChildNode(new ON_XMLNode(ON_DISPLACEMENT_SUB)); - auto* sub = new SubItem(*sub_node); + ON_XMLNode node(ON_DISPLACEMENT_SUB); + auto* sub = new SubItem(node); m_impl_dsp->m_subs.Append(sub); return *sub; @@ -347,7 +493,7 @@ void ON_Displacement::DeleteAllSubItems(void) ON_Displacement::SubItem* ON_Displacement::FindSubItem(const int index) const { auto it = GetSubItemIterator(); - while (auto* sub = it.Next()) + while (SubItem* sub = it.Next()) { if (sub->Index() == index) return sub; @@ -359,10 +505,10 @@ ON_Displacement::SubItem* ON_Displacement::FindSubItem(const int index) const class ON_Displacement::SubItem::CImpl : public ON_InternalXMLImpl { public: - CImpl(ON_XMLNode& sub_node) : ON_InternalXMLImpl(&sub_node) { } + CImpl(const ON_XMLNode& sub_node) { Node() = sub_node; } }; -ON_Displacement::SubItem::SubItem(ON_XMLNode& sub_node) +ON_Displacement::SubItem::SubItem(const ON_XMLNode& sub_node) { m_impl = new CImpl(sub_node); } @@ -465,6 +611,11 @@ void ON_Displacement::SubItem::SetWhitePoint(double w) m_impl->SetParameter(ON_DISPLACEMENT_SUB_WHITE_POINT, w); } +void ON_Displacement::SubItem::ToXML(ON_XMLNode& node) const +{ + node = m_impl->Node(); +} + class ON_Displacement::SubItemIterator::CImpl { public: @@ -498,27 +649,112 @@ ON_Displacement::SubItem* ON_Displacement::SubItemIterator::Next(void) return m_impl->Next(); } +ON_UUID ON_Displacement::Uuid(void) const +{ + // The unique id of the mesh modifier is the same as the id of its user data. + return ON_DisplacementUserData::Uuid(); +} + +int ON_Displacement::Defaults::RefineStepCount(void) { return 1; } +int ON_Displacement::Defaults::FairingAmount(void) { return 4; } +int ON_Displacement::Defaults::FaceLimit(void) { return 10000; } +int ON_Displacement::Defaults::ChannelNumber(void) { return 1; } +int ON_Displacement::Defaults::MeshMemoryLimit(void) { return 512; } +double ON_Displacement::Defaults::BlackPoint(void) { return 0.0; } +double ON_Displacement::Defaults::WhitePoint(void) { return 1.0; } +double ON_Displacement::Defaults::SweepPitch(void) { return 1000.0; } +double ON_Displacement::Defaults::RefineSensitivity(void) { return 0.5; } +double ON_Displacement::Defaults::PostWeldAngle(void) { return 40.0; } +double ON_Displacement::Defaults::AbsoluteTolerance(void) { return 0.001; } + +ON_Displacement::SweepResolutionFormulas ON_Displacement::Defaults::SweepResolutionFormula(void) +{ + return SweepResolutionFormulas::Default; +} + //////////////////////////////////////////////////////////////// // // Edge Softening // //////////////////////////////////////////////////////////////// -#define ON_EDGE_SOFTENING_ROOT L"edge-softening-object-data" - #define ON_EDGE_SOFTENING_ON L"on" - #define ON_EDGE_SOFTENING_SOFTENING L"softening" - #define ON_EDGE_SOFTENING_CHAMFER L"chamfer" - #define ON_EDGE_SOFTENING_UNWELD L"unweld" - #define ON_EDGE_SOFTENING_FORCE_SOFTENING L"force-softening" - #define ON_EDGE_SOFTENING_EDGE_THRESHOLD L"edge-threshold" +ON_OBJECT_IMPLEMENT(ON_EdgeSofteningUserData, ON_UserData, "CB5EB395-BF1B-4112-8F2F-F728FCE8169C"); + +ON_UUID ON_EdgeSofteningUserData::Uuid(void) +{ + static const ON_UUID uuid = { 0x8cbe6160, 0x5cbd, 0x4b4d, { 0x8c, 0xd2, 0x7c, 0xe0, 0xa7, 0xc8, 0xc2, 0xd8 } }; + return uuid; +} + +ON_EdgeSofteningUserData::ON_EdgeSofteningUserData() +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + SetToDefaults(); +} + +ON_EdgeSofteningUserData::ON_EdgeSofteningUserData(const ON_EdgeSofteningUserData& ud) + : + ON_XMLUserData(ud) // CRITICAL - Be sure to call base class. +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + // DO NOT SET OTHER ON_UserData fields + // In particular, do not set m_userdata_copycount + *this = ud; +} + +bool ON_EdgeSofteningUserData::GetDescription(ON_wString& s) +{ + s = L"EdgeSoftening object data"; + return true; +} + +const ON_EdgeSofteningUserData& ON_EdgeSofteningUserData::operator = (const ON_EdgeSofteningUserData& ud) +{ + if (this != &ud) + ON_XMLUserData::operator = (ud); + + return *this; +} + +void ON_EdgeSofteningUserData::SetToDefaults(void) const +{ + auto& ud = const_cast(*this); + ud.Clear(); + + ON_XMLProperty prop; + ON_XMLNode* root = ud.XMLRootForWrite().AttachChildNode(new ON_XMLNode(ON_EDGE_SOFTENING_ROOT)); + + ON_EdgeSoftening::Defaults d; + + ON_XMLParameters p(*root); + p.SetParam(ON_EDGE_SOFTENING_ON, false); + p.SetParam(ON_EDGE_SOFTENING_SOFTENING, d.Softening()); + p.SetParam(ON_EDGE_SOFTENING_CHAMFER, d.Chamfer()); + p.SetParam(ON_EDGE_SOFTENING_UNWELD, d.Faceted()); + p.SetParam(ON_EDGE_SOFTENING_FORCE_SOFTENING, d.ForceSoftening()); + p.SetParam(ON_EDGE_SOFTENING_EDGE_THRESHOLD, d.EdgeAngleThreshold()); +} + +void ON_EdgeSofteningUserData::ReportVersionError(void) const +{ + //RhinoMessageBox(L"Version error", L"EdgeSoftening", MB_OK | MB_ICONERROR); +} ON_EdgeSoftening::ON_EdgeSoftening() + : + ON_MeshModifier(ON_XMLNode(ON_EDGE_SOFTENING_ROOT)) { } -ON_EdgeSoftening::ON_EdgeSoftening(ON_XMLNode& model_node) +ON_EdgeSoftening::ON_EdgeSoftening(const ON_XMLNode& node) : - ON_MeshModifier(model_node) + ON_MeshModifier(node) { } @@ -619,26 +855,105 @@ void ON_EdgeSoftening::SetForceSoftening(bool b) m_impl->SetParameter(ON_EDGE_SOFTENING_FORCE_SOFTENING, b); } +ON_UUID ON_EdgeSoftening::Uuid(void) const +{ + // The unique id of the mesh modifier is the same as the id of its user data. + return ON_EdgeSofteningUserData::Uuid(); +} + +bool ON_EdgeSoftening::Defaults::Chamfer(void) { return false; } +bool ON_EdgeSoftening::Defaults::Faceted(void) { return false; } +bool ON_EdgeSoftening::Defaults::ForceSoftening(void) { return false; } +double ON_EdgeSoftening::Defaults::Softening(void) { return 0.1; } +double ON_EdgeSoftening::Defaults::EdgeAngleThreshold(void) { return 5.0; } + //////////////////////////////////////////////////////////////// // // Thickening // //////////////////////////////////////////////////////////////// -#define ON_THICKNESS_ROOT L"thickening-object-data" - #define ON_THICKNESS_ON L"on" - #define ON_THICKNESS_DISTANCE L"distance" - #define ON_THICKNESS_SOLID L"solid" - #define ON_THICKNESS_BOTH_SIDES L"both-sides" - #define ON_THICKNESS_OFFSET_ONLY L"offset-only" +ON_OBJECT_IMPLEMENT(ON_ThickeningUserData, ON_UserData, "AA03D9C3-4CCF-4431-A06E-25F38CF3913F"); + +ON_UUID ON_ThickeningUserData::Uuid(void) +{ + static const ON_UUID uuid = { 0x6aa7ccc3, 0x2721, 0x410f, { 0xaa, 0x56, 0xe8, 0xab, 0x4f, 0x3e, 0xce, 0x67 } }; + return uuid; +} + +ON_ThickeningUserData::ON_ThickeningUserData() +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + SetToDefaults(); +} + +ON_ThickeningUserData::ON_ThickeningUserData(const ON_ThickeningUserData& ud) + : + ON_XMLUserData(ud) // CRITICAL - Be sure to call base class. +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + // DO NOT SET OTHER ON_UserData fields + // In particular, do not set m_userdata_copycount + *this = ud; +} + +const ON_ThickeningUserData& ON_ThickeningUserData::operator = (const ON_ThickeningUserData& ud) +{ + if (this != &ud) + ON_XMLUserData::operator = (ud); + + return *this; +} + +void ON_ThickeningUserData::SetToDefaults(void) const +{ + auto& ud = const_cast(*this); + ud.Clear(); + + ON_XMLProperty prop; + ON_XMLNode* root = ud.XMLRootForWrite().AttachChildNode(new ON_XMLNode(ON_THICKENING_ROOT)); + + ON_Thickening::Defaults d; + + ON_XMLParameters p(*root); + p.SetParam(ON_THICKENING_ON, false); + p.SetParam(ON_THICKENING_SOLID, d.Solid()); + p.SetParam(ON_THICKENING_BOTH_SIDES, d.BothSides()); + p.SetParam(ON_THICKENING_OFFSET_ONLY, d.OffsetOnly()); + p.SetParam(ON_THICKENING_DISTANCE, d.Distance()); +} + +bool ON_ThickeningUserData::GetDescription(ON_wString& s) +{ + s = L"Thickness object data"; + return true; +} + +void ON_ThickeningUserData::ReportVersionError(void) const +{ + //RhinoMessageBox(L"Version error", L"Thickness", MB_OK | MB_ICONERROR); +} + +bool ON_ThickeningUserData::Transform(const ON_Xform& xform) +{ + return ON_XMLUserData::Transform(xform); +} ON_Thickening::ON_Thickening() + : + ON_MeshModifier(ON_XMLNode(ON_THICKENING_ROOT)) { } -ON_Thickening::ON_Thickening(ON_XMLNode& model_node) +ON_Thickening::ON_Thickening(const ON_XMLNode& node) : - ON_MeshModifier(model_node) + ON_MeshModifier(node) { } @@ -679,79 +994,153 @@ bool ON_Thickening::operator != (const ON_Thickening& t) const bool ON_Thickening::On(void) const { - return m_impl->GetParameter(ON_THICKNESS_ON, false).AsBool(); + return m_impl->GetParameter(ON_THICKENING_ON, false).AsBool(); } void ON_Thickening::SetOn(bool b) { - m_impl->SetParameter(ON_THICKNESS_ON, b); + m_impl->SetParameter(ON_THICKENING_ON, b); } double ON_Thickening::Distance(void) const { - return m_impl->GetParameter(ON_THICKNESS_DISTANCE, 0.1).AsDouble(); + return m_impl->GetParameter(ON_THICKENING_DISTANCE, 0.1).AsDouble(); } void ON_Thickening::SetDistance(double d) { - m_impl->SetParameter(ON_THICKNESS_DISTANCE, d); + m_impl->SetParameter(ON_THICKENING_DISTANCE, d); } bool ON_Thickening::Solid(void) const { - return m_impl->GetParameter(ON_THICKNESS_SOLID, true).AsBool(); + return m_impl->GetParameter(ON_THICKENING_SOLID, true).AsBool(); } void ON_Thickening::SetSolid(bool b) { - m_impl->SetParameter(ON_THICKNESS_SOLID, b); + m_impl->SetParameter(ON_THICKENING_SOLID, b); } bool ON_Thickening::OffsetOnly(void) const { - return m_impl->GetParameter(ON_THICKNESS_OFFSET_ONLY, false).AsBool(); + return m_impl->GetParameter(ON_THICKENING_OFFSET_ONLY, false).AsBool(); } void ON_Thickening::SetOffsetOnly(bool b) { - m_impl->SetParameter(ON_THICKNESS_OFFSET_ONLY, b); + m_impl->SetParameter(ON_THICKENING_OFFSET_ONLY, b); } bool ON_Thickening::BothSides(void) const { - return m_impl->GetParameter(ON_THICKNESS_BOTH_SIDES, false).AsBool(); + return m_impl->GetParameter(ON_THICKENING_BOTH_SIDES, false).AsBool(); } void ON_Thickening::SetBothSides(bool b) { - m_impl->SetParameter(ON_THICKNESS_BOTH_SIDES, b); + m_impl->SetParameter(ON_THICKENING_BOTH_SIDES, b); } +ON_UUID ON_Thickening::Uuid(void) const +{ + // The unique id of the mesh modifier is the same as the id of its user data. + return ON_ThickeningUserData::Uuid(); +} + +bool ON_Thickening::Defaults::Solid(void) { return true; } +bool ON_Thickening::Defaults::BothSides(void) { return false; } +bool ON_Thickening::Defaults::OffsetOnly(void) { return false; } +double ON_Thickening::Defaults::Distance(void) { return 0.1; } + //////////////////////////////////////////////////////////////// // // CurvePiping // //////////////////////////////////////////////////////////////// -#define ON_CURVE_PIPING_ROOT L"curve-piping-object-data" - #define ON_CURVE_PIPING_ON L"on" - #define ON_CURVE_PIPING_SEGMENTS L"segments" - #define ON_CURVE_PIPING_RADIUS L"radius" - #define ON_CURVE_PIPING_ACCURACY L"accuracy" - #define ON_CURVE_PIPING_WELD L"weld" - #define ON_CURVE_PIPING_CAP_TYPE L"cap-type" - #define ON_CURVE_PIPING_NONE L"none" - #define ON_CURVE_PIPING_FLAT L"flat" - #define ON_CURVE_PIPING_BOX L"box" - #define ON_CURVE_PIPING_DOME L"dome" +ON_OBJECT_IMPLEMENT(ON_CurvePipingUserData, ON_UserData, "2D5AFEA9-F458-4079-992F-C2D405D9383B"); + +ON_UUID ON_CurvePipingUserData::Uuid(void) +{ + static const ON_UUID uuid = { 0x2b1a758e, 0x7cb1, 0x45ab, { 0xa5, 0xbf, 0xdf, 0xcd, 0x6d, 0x3d, 0x13, 0x6d } }; + return uuid; +} + +ON_CurvePipingUserData::ON_CurvePipingUserData() +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + SetToDefaults(); +} + +ON_CurvePipingUserData::ON_CurvePipingUserData(const ON_CurvePipingUserData& ud) + : + ON_XMLUserData(ud) // CRITICAL - Be sure to call base class. +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + // DO NOT SET OTHER ON_UserData fields + // In particular, do not set m_userdata_copycount + *this = ud; +} + +const ON_CurvePipingUserData& ON_CurvePipingUserData::operator = (const ON_CurvePipingUserData& ud) +{ + if (this != &ud) + ON_XMLUserData::operator = (ud); + + return *this; +} + +void ON_CurvePipingUserData::SetToDefaults(void) const +{ + auto& ud = const_cast(*this); + ud.Clear(); + + ON_XMLProperty prop; + ON_XMLNode* root = ud.XMLRootForWrite().AttachChildNode(new ON_XMLNode(ON_CURVE_PIPING_ROOT)); + + ON_CurvePiping::Defaults d; + + ON_XMLParameters p(*root); + p.SetParam(ON_CURVE_PIPING_ON, false); + p.SetParam(ON_CURVE_PIPING_RADIUS, d.Radius()); + p.SetParam(ON_CURVE_PIPING_SEGMENTS, d.Segments()); + p.SetParam(ON_CURVE_PIPING_ACCURACY, d.Accuracy()); + p.SetParam(ON_CURVE_PIPING_WELD, !d.Faceted()); // 'Weld' is the inverse of 'Faceted'. + p.SetParam(ON_CURVE_PIPING_CAP_TYPE, L"dome"); +} + +bool ON_CurvePipingUserData::GetDescription(ON_wString& s) +{ + s = L"CurvePiping object data"; + return true; +} + +void ON_CurvePipingUserData::ReportVersionError(void) const +{ + //RhinoMessageBox(L"Version error", L"CurvePiping", MB_OK | MB_ICONERROR); +} + +bool ON_CurvePipingUserData::Transform(const ON_Xform& xform) +{ + return ON_XMLUserData::Transform(xform); +} ON_CurvePiping::ON_CurvePiping() + : + ON_MeshModifier(ON_XMLNode(ON_CURVE_PIPING_ROOT)) { } -ON_CurvePiping::ON_CurvePiping(ON_XMLNode& model_node) +ON_CurvePiping::ON_CurvePiping(const ON_XMLNode& node) : - ON_MeshModifier(model_node) + ON_MeshModifier(node) { } @@ -822,12 +1211,14 @@ void ON_CurvePiping::SetSegments(int s) bool ON_CurvePiping::Faceted(void) const { - return m_impl->GetParameter(ON_CURVE_PIPING_WELD, false).AsBool(); + // 'Weld' is the inverse of 'Faceted'. + return !m_impl->GetParameter(ON_CURVE_PIPING_WELD, true).AsBool(); } void ON_CurvePiping::SetFaceted(bool b) { - m_impl->SetParameter(ON_CURVE_PIPING_WELD, b); + // 'Weld' is the inverse of 'Faceted'. + m_impl->SetParameter(ON_CURVE_PIPING_WELD, !b); } int ON_CurvePiping::Accuracy(void) const @@ -854,7 +1245,7 @@ static const wchar_t* CapTypeToString(ON_CurvePiping::CapTypes ct) ON_CurvePiping::CapTypes ON_CurvePiping::CapType(void) const { - const auto s = m_impl->GetParameter(ON_CURVE_PIPING_CAP_TYPE, L"").AsString(); + const ON_wString s = m_impl->GetParameter(ON_CURVE_PIPING_CAP_TYPE, L"").AsString(); if (s == ON_CURVE_PIPING_FLAT) return ON_CurvePiping::CapTypes::Flat; if (s == ON_CURVE_PIPING_BOX) return ON_CurvePiping::CapTypes::Box; @@ -865,63 +1256,147 @@ ON_CurvePiping::CapTypes ON_CurvePiping::CapType(void) const void ON_CurvePiping::SetCapType(CapTypes ct) { - const auto* s = CapTypeToString(ct); + const wchar_t* s = CapTypeToString(ct); m_impl->SetParameter(ON_CURVE_PIPING_CAP_TYPE, s); } +ON_UUID ON_CurvePiping::Uuid(void) const +{ + // The unique id of the mesh modifier is the same as the id of its user data. + return ON_CurvePipingUserData::Uuid(); +} + +bool ON_CurvePiping::Defaults::Faceted(void) { return false; } +int ON_CurvePiping::Defaults::Segments(void) { return 16; } +int ON_CurvePiping::Defaults::Accuracy(void) { return 50; } +double ON_CurvePiping::Defaults::Radius(void) { return 1.0; } + +ON_CurvePiping::CapTypes ON_CurvePiping::Defaults::CapType(void) +{ + return CapTypes::Dome; +} + //////////////////////////////////////////////////////////////// // // Shutlining // //////////////////////////////////////////////////////////////// -#define ON_SHUTLINING_ROOT L"shut-lining-object-data" - #define ON_SHUTLINING_ON L"on" - #define ON_SHUTLINING_CURVE L"curve" - #define ON_SHUTLINING_CURVE_UUID L"uuid" - #define ON_SHUTLINING_CURVE_ENABLED L"enabled" - #define ON_SHUTLINING_CURVE_RADIUS L"radius" - #define ON_SHUTLINING_CURVE_PROFILE L"profile" - #define ON_SHUTLINING_CURVE_PULL L"pull" - #define ON_SHUTLINING_CURVE_IS_BUMP L"is-bump" - #define ON_SHUTLINING_FACETED L"faceted" - #define ON_SHUTLINING_AUTO_UPDATE L"auto-update" - #define ON_SHUTLINING_FORCE_UPDATE L"force-update" +ON_OBJECT_IMPLEMENT(ON_ShutLiningUserData, ON_UserData, "429DCD06-5643-4254-BDE8-C0557F8FD083"); -class ON_Shutlining::CImplSL +ON_UUID ON_ShutLiningUserData::Uuid(void) +{ + static const ON_UUID uuid = { 0x7506ebe, 0x1d69, 0x4345, { 0x9f, 0xd, 0x2b, 0x9a, 0xa1, 0x90, 0x6e, 0xef } }; + return uuid; +} + +ON_ShutLiningUserData::ON_ShutLiningUserData() +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + SetToDefaults(); +} + +ON_ShutLiningUserData::ON_ShutLiningUserData(const ON_ShutLiningUserData& ud) + : + ON_XMLUserData(ud) // CRITICAL - Be sure to call base class. +{ + m_userdata_uuid = Uuid(); + + m_application_uuid = ON_MeshModifier::PlugInId(); + + // DO NOT SET OTHER ON_UserData fields + // In particular, do not set m_userdata_copycount + *this = ud; +} + +const ON_ShutLiningUserData& ON_ShutLiningUserData::operator = (const ON_ShutLiningUserData& ud) +{ + if (this != &ud) + ON_XMLUserData::operator = (ud); + + return *this; +} + +void ON_ShutLiningUserData::SetToDefaults(void) const +{ + auto& ud = const_cast(*this); + ud.Clear(); + + ON_XMLProperty prop; + ON_XMLNode* root = ud.XMLRootForWrite().AttachChildNode(new ON_XMLNode(ON_SHUTLINING_ROOT)); + + ON_XMLParameters p(*root); + p.SetParam(ON_SHUTLINING_ON, false); + p.SetParam(ON_SHUTLINING_FACETED, ON_ShutLining::Defaults::Faceted()); + p.SetParam(ON_SHUTLINING_AUTO_UPDATE, ON_ShutLining::Defaults::AutoUpdate()); + p.SetParam(ON_SHUTLINING_FORCE_UPDATE, ON_ShutLining::Defaults::ForceUpdate()); +} + +bool ON_ShutLiningUserData::GetDescription(ON_wString& s) +{ + s = L"ShutLining object data"; + return true; +} + +void ON_ShutLiningUserData::ReportVersionError(void) const +{ + //RhinoMessageBox(L"Version error", L"ShutLining", MB_OK | MB_ICONERROR); +} + +bool ON_ShutLiningUserData::Transform(const ON_Xform& xform) +{ + return ON_XMLUserData::Transform(xform); +} + +class ON_ShutLining::CImplSL { public: ON_SimpleArray m_curves; }; -ON_Shutlining::ON_Shutlining() +ON_ShutLining::ON_ShutLining() + : + ON_MeshModifier(ON_XMLNode(ON_SHUTLINING_ROOT)) { m_impl_sl = new CImplSL; } -ON_Shutlining::ON_Shutlining(ON_XMLNode& model_node) - : - ON_MeshModifier(model_node) +ON_ShutLining::ON_ShutLining(const ON_XMLNode& sl_node) { m_impl_sl = new CImplSL; - auto it = model_node.GetChildIterator(); - while (auto* child_node = it.GetNextChild()) + // Iterate over the shutlining node looking at each child node's name. If the child + // node is a curve node, create a curve object to hold the curve XML. Otherwise add + // a copy of the child node to a new shutlining node. + ON_XMLNode new_sl_node(sl_node.TagName()); + + auto it = sl_node.GetChildIterator(); + while (ON_XMLNode* child_node = it.GetNextChild()) { if (ON_SHUTLINING_CURVE == child_node->TagName()) { m_impl_sl->m_curves.Append(new Curve(*child_node)); } + else + { + new_sl_node.AttachChildNode(new ON_XMLNode(*child_node)); + } } + + // Copy the new shutlining node to our node. It only contains shutlining XML with no curve nodes. + m_impl->Node() = new_sl_node; } -ON_Shutlining::ON_Shutlining(const ON_Shutlining& sl) +ON_ShutLining::ON_ShutLining(const ON_ShutLining& sl) { m_impl_sl = new CImplSL; operator = (sl); } -ON_Shutlining::~ON_Shutlining() +ON_ShutLining::~ON_ShutLining() { DeleteAllCurves(); @@ -929,7 +1404,7 @@ ON_Shutlining::~ON_Shutlining() m_impl_sl = nullptr; } -const ON_Shutlining& ON_Shutlining::operator = (const ON_Shutlining& sl) +const ON_ShutLining& ON_ShutLining::operator = (const ON_ShutLining& sl) { if (this != &sl) { @@ -942,9 +1417,9 @@ const ON_Shutlining& ON_Shutlining::operator = (const ON_Shutlining& sl) // Copy curves. DeleteAllCurves(); auto it = sl.GetCurveIterator(); - while (auto* sl_curve = it.Next()) + while (Curve* sl_curve = it.Next()) { - auto& new_curve = AddCurve(); + Curve& new_curve = AddCurve(); new_curve = *sl_curve; } } @@ -952,10 +1427,10 @@ const ON_Shutlining& ON_Shutlining::operator = (const ON_Shutlining& sl) return *this; } -ON_Shutlining::Curve* ON_Shutlining::FindCurve(const ON_UUID& id) const +ON_ShutLining::Curve* ON_ShutLining::FindCurve(const ON_UUID& id) const { auto it = GetCurveIterator(); - while (auto* curve = it.Next()) + while (Curve* curve = it.Next()) { if (curve->Id() == id) return curve; @@ -964,7 +1439,7 @@ ON_Shutlining::Curve* ON_Shutlining::FindCurve(const ON_UUID& id) const return nullptr; } -bool ON_Shutlining::operator == (const ON_Shutlining& sl) const +bool ON_ShutLining::operator == (const ON_ShutLining& sl) const { if (On() != sl.On()) return false; if (Faceted() != sl.Faceted()) return false; @@ -972,17 +1447,17 @@ bool ON_Shutlining::operator == (const ON_Shutlining& sl) const if (ForceUpdate() != sl.ForceUpdate()) return false; auto it1 = GetCurveIterator(); - while (auto* curve = it1.Next()) + while (Curve* curve = it1.Next()) { - const auto* sl_curve = sl.FindCurve(curve->Id()); + const Curve* sl_curve = sl.FindCurve(curve->Id()); if (nullptr == sl_curve) return false; } auto it2 = sl.GetCurveIterator(); - while (auto* sl_curve = it2.Next()) + while (Curve* sl_curve = it2.Next()) { - const auto* curve = FindCurve(sl_curve->Id()); + const Curve* curve = FindCurve(sl_curve->Id()); if ((nullptr == curve) || (*curve != *sl_curve)) return false; } @@ -990,66 +1465,66 @@ bool ON_Shutlining::operator == (const ON_Shutlining& sl) const return true; } -bool ON_Shutlining::operator != (const ON_Shutlining& sl) const +bool ON_ShutLining::operator != (const ON_ShutLining& sl) const { return !(operator == (sl)); } -bool ON_Shutlining::On(void) const +bool ON_ShutLining::On(void) const { return m_impl->GetParameter(ON_SHUTLINING_ON, false).AsBool(); } -void ON_Shutlining::SetOn(bool b) +void ON_ShutLining::SetOn(bool b) { m_impl->SetParameter(ON_SHUTLINING_ON, b); } -bool ON_Shutlining::Faceted(void) const +bool ON_ShutLining::Faceted(void) const { return m_impl->GetParameter(ON_SHUTLINING_FACETED, false).AsBool(); } -void ON_Shutlining::SetFaceted(bool b) +void ON_ShutLining::SetFaceted(bool b) { m_impl->SetParameter(ON_SHUTLINING_FACETED, b); } -bool ON_Shutlining::AutoUpdate(void) const +bool ON_ShutLining::AutoUpdate(void) const { return m_impl->GetParameter(ON_SHUTLINING_AUTO_UPDATE, false).AsBool(); } -void ON_Shutlining::SetAutoUpdate(bool b) +void ON_ShutLining::SetAutoUpdate(bool b) { m_impl->SetParameter(ON_SHUTLINING_AUTO_UPDATE, b); } -bool ON_Shutlining::ForceUpdate(void) const +bool ON_ShutLining::ForceUpdate(void) const { return m_impl->GetParameter(ON_SHUTLINING_FORCE_UPDATE, false).AsBool(); } -void ON_Shutlining::SetForceUpdate(bool b) +void ON_ShutLining::SetForceUpdate(bool b) { m_impl->SetParameter(ON_SHUTLINING_FORCE_UPDATE, b); } -ON_Shutlining::CurveIterator ON_Shutlining::GetCurveIterator(void) const +ON_ShutLining::CurveIterator ON_ShutLining::GetCurveIterator(void) const { return CurveIterator(*this); } -ON_Shutlining::Curve& ON_Shutlining::AddCurve(void) +ON_ShutLining::Curve& ON_ShutLining::AddCurve(void) { - auto* curve_node = m_impl->Node().AttachChildNode(new ON_XMLNode(ON_SHUTLINING_CURVE)); - auto* curve = new Curve(*curve_node); + ON_XMLNode* curve_node = m_impl->Node().AttachChildNode(new ON_XMLNode(ON_SHUTLINING_CURVE)); + Curve* curve = new Curve(*curve_node); m_impl_sl->m_curves.Append(curve); return *curve; } -void ON_Shutlining::DeleteAllCurves(void) +void ON_ShutLining::DeleteAllCurves(void) { for (int i = 0; i < m_impl_sl->m_curves.Count(); i++) { @@ -1059,14 +1534,38 @@ void ON_Shutlining::DeleteAllCurves(void) m_impl_sl->m_curves.Destroy(); } -class ON_Shutlining::Curve::CImpl final +ON_XMLNode* ON_ShutLining::AddChildXML(ON_XMLRootNode& root) const +{ + ON_XMLNode* sl_node = ON_MeshModifier::AddChildXML(root); + + for (int i = 0; i < m_impl_sl->m_curves.Count(); i++) + { + ON_XMLNode* curve_node = sl_node->AttachChildNode(new ON_XMLNode(L"")); + m_impl_sl->m_curves[i]->ToXML(*curve_node); + } + + return sl_node; +} + +ON_UUID ON_ShutLining::Uuid(void) const +{ + // The unique id of the mesh modifier is the same as the id of its user data. + return ON_ShutLiningUserData::Uuid(); +} + +bool ON_ShutLining::Defaults::Faceted(void) { return false; } +bool ON_ShutLining::Defaults::AutoUpdate(void) { return false; } +bool ON_ShutLining::Defaults::ForceUpdate(void) { return false; } +double ON_ShutLining::Defaults::Tolerance(void) { return 0.001; } + +class ON_ShutLining::Curve::CImpl final { public: - CImpl(ON_XMLNode& n) : m_node(n) { } + CImpl(const ON_XMLNode& n) : m_node(n) { } ON_XMLVariant GetParam(const wchar_t* param_name, const ON_XMLVariant& def) const { - const auto* child_node = m_node.GetNamedChild(param_name); + const ON_XMLNode* child_node = m_node.GetNamedChild(param_name); if (nullptr != child_node) return child_node->GetDefaultProperty().GetValue(); @@ -1075,25 +1574,26 @@ public: void SetParam(const wchar_t* param_name, const ON_XMLVariant& v) { - const auto* child_node = m_node.CreateNodeAtPath(param_name); + const ON_XMLNode* child_node = m_node.CreateNodeAtPath(param_name); child_node->GetDefaultProperty().SetValue(v); } - ON_XMLNode& m_node; +public: + ON_XMLNode m_node; }; -ON_Shutlining::Curve::Curve(ON_XMLNode& curve_node) +ON_ShutLining::Curve::Curve(const ON_XMLNode& curve_node) { m_impl = new CImpl(curve_node); } -ON_Shutlining::Curve::~Curve() +ON_ShutLining::Curve::~Curve() { delete m_impl; m_impl = nullptr; } -const ON_Shutlining::Curve& ON_Shutlining::Curve::operator = (const ON_Shutlining::Curve& c) +const ON_ShutLining::Curve& ON_ShutLining::Curve::operator = (const ON_ShutLining::Curve& c) { if (this != &c) { @@ -1108,7 +1608,7 @@ const ON_Shutlining::Curve& ON_Shutlining::Curve::operator = (const ON_Shutlinin return *this; } -bool ON_Shutlining::Curve::operator == (const Curve& c) const +bool ON_ShutLining::Curve::operator == (const Curve& c) const { if (Id() != c.Id()) return false; if (Enabled() != c.Enabled()) return false; @@ -1120,75 +1620,86 @@ bool ON_Shutlining::Curve::operator == (const Curve& c) const return true; } -bool ON_Shutlining::Curve::operator != (const Curve& c) const +bool ON_ShutLining::Curve::operator != (const Curve& c) const { return !(operator == (c)); } -ON_UUID ON_Shutlining::Curve::Id(void) const +ON_UUID ON_ShutLining::Curve::Id(void) const { return m_impl->GetParam(ON_SHUTLINING_CURVE_UUID, ON_nil_uuid); } -void ON_Shutlining::Curve::SetId(const ON_UUID& id) +void ON_ShutLining::Curve::SetId(const ON_UUID& id) { m_impl->SetParam(ON_SHUTLINING_CURVE_UUID, id); } -double ON_Shutlining::Curve::Radius(void) const +double ON_ShutLining::Curve::Radius(void) const { return m_impl->GetParam(ON_SHUTLINING_CURVE_RADIUS, 1.0); } -void ON_Shutlining::Curve::SetRadius(double d) +void ON_ShutLining::Curve::SetRadius(double d) { m_impl->SetParam(ON_SHUTLINING_CURVE_RADIUS, d); } -int ON_Shutlining::Curve::Profile(void) const +int ON_ShutLining::Curve::Profile(void) const { return m_impl->GetParam(ON_SHUTLINING_CURVE_PROFILE, 0); } -void ON_Shutlining::Curve::SetProfile(int p) +void ON_ShutLining::Curve::SetProfile(int p) { m_impl->SetParam(ON_SHUTLINING_CURVE_PROFILE, p); } -bool ON_Shutlining::Curve::Enabled(void) const +bool ON_ShutLining::Curve::Enabled(void) const { return m_impl->GetParam(ON_SHUTLINING_CURVE_ENABLED, false); } -void ON_Shutlining::Curve::SetEnabled(bool b) +void ON_ShutLining::Curve::SetEnabled(bool b) { m_impl->SetParam(ON_SHUTLINING_CURVE_ENABLED, b); } -bool ON_Shutlining::Curve::Pull(void) const +bool ON_ShutLining::Curve::Pull(void) const { return m_impl->GetParam(ON_SHUTLINING_CURVE_PULL, false); } -void ON_Shutlining::Curve::SetPull(bool b) +void ON_ShutLining::Curve::SetPull(bool b) { m_impl->SetParam(ON_SHUTLINING_CURVE_PULL, b); } -bool ON_Shutlining::Curve::IsBump(void) const +bool ON_ShutLining::Curve::IsBump(void) const { return m_impl->GetParam(ON_SHUTLINING_CURVE_IS_BUMP, false); } -void ON_Shutlining::Curve::SetIsBump(bool b) +void ON_ShutLining::Curve::SetIsBump(bool b) { m_impl->SetParam(ON_SHUTLINING_CURVE_IS_BUMP, b); } -class ON_Shutlining::CurveIterator::CImpl +void ON_ShutLining::Curve::ToXML(ON_XMLNode& node) const +{ + node = m_impl->m_node; +} + +bool ON_ShutLining::Curve::Defaults::Enabled(void) { return true; } +bool ON_ShutLining::Curve::Defaults::Pull(void) { return true; } +bool ON_ShutLining::Curve::Defaults::IsBump(void) { return false; } +int ON_ShutLining::Curve::Defaults::Profile(void) { return 1; } +double ON_ShutLining::Curve::Defaults::Radius(void) { return 0.1; } + +class ON_ShutLining::CurveIterator::CImpl { public: - CImpl(const ON_Shutlining& sl) : m_sl(sl) { } + CImpl(const ON_ShutLining& sl) : m_sl(sl) { } Curve* Next(void) { @@ -1198,22 +1709,22 @@ public: return m_sl.m_impl_sl->m_curves[m_index++]; } - const ON_Shutlining& m_sl; + const ON_ShutLining& m_sl; int m_index = 0; }; -ON_Shutlining::CurveIterator::CurveIterator(const ON_Shutlining& sl) +ON_ShutLining::CurveIterator::CurveIterator(const ON_ShutLining& sl) { m_impl = new CImpl(sl); } -ON_Shutlining::CurveIterator::~CurveIterator() +ON_ShutLining::CurveIterator::~CurveIterator() { delete m_impl; m_impl = nullptr; } -ON_Shutlining::Curve* ON_Shutlining::CurveIterator::Next(void) +ON_ShutLining::Curve* ON_ShutLining::CurveIterator::Next(void) { return m_impl->Next(); } @@ -1223,85 +1734,113 @@ ON_Shutlining::Curve* ON_Shutlining::CurveIterator::Next(void) class ON_MeshModifiers::CImpl { public: - CImpl(ON_XMLNode& node); ~CImpl(); - ON_XMLNode m_displacement_node; - ON_XMLNode m_edge_softening_node; - ON_XMLNode m_thickening_node; - ON_XMLNode m_curve_piping_node; - ON_XMLNode m_shutlining_node; + void LoadFromXML(const ON_XMLRootNode& root); + void SaveToXML(ON_XMLRootNode& root) const; + + void DeleteAll(void); ON_Displacement * m_displacement = nullptr; ON_EdgeSoftening* m_edge_softening = nullptr; ON_Thickening * m_thickening = nullptr; ON_CurvePiping * m_curve_piping = nullptr; - ON_Shutlining * m_shutlining = nullptr; + ON_ShutLining * m_shut_lining = nullptr; }; -ON_MeshModifiers::CImpl::CImpl(ON_XMLNode& model_node) - : - m_displacement_node (ON_DISPLACEMENT_ROOT), - m_edge_softening_node(ON_EDGE_SOFTENING_ROOT), - m_thickening_node (ON_THICKNESS_ROOT), - m_curve_piping_node (ON_CURVE_PIPING_ROOT), - m_shutlining_node (ON_SHUTLINING_ROOT) +void ON_MeshModifiers::CImpl::LoadFromXML(const ON_XMLRootNode& root) { - // Iterate over the child nodes of the incoming model node and copy them to the relevent mesh modifier nodes. - auto it = model_node.GetChildIterator(); - while (auto* child_node = it.GetNextChild()) + auto it = root.GetChildIterator(); + while (ON_XMLNode* child_node = it.GetNextChild()) { - const auto& s = child_node->TagName(); + const ON_wString& s = child_node->TagName(); if (ON_DISPLACEMENT_ROOT == s) { - m_displacement_node = *child_node; + m_displacement = new ON_Displacement(*child_node); } else if (ON_EDGE_SOFTENING_ROOT == s) { - m_edge_softening_node = *child_node; + m_edge_softening = new ON_EdgeSoftening(*child_node); } else - if (ON_THICKNESS_ROOT == s) + if (ON_THICKENING_ROOT == s) { - m_thickening_node = *child_node; + m_thickening = new ON_Thickening(*child_node); } else if (ON_CURVE_PIPING_ROOT == s) { - m_curve_piping_node = *child_node; + m_curve_piping = new ON_CurvePiping(*child_node); } else if (ON_SHUTLINING_ROOT == s) { - m_shutlining_node = *child_node; + m_shut_lining = new ON_ShutLining(*child_node); } } +} - // Create the necessary mesh modifiers using the above-initialized nodes. The mesh modifiers store pointers - // to these nodes. This is safe because the nodes have the same lifetime as the mesh modifiers. - m_displacement = new ON_Displacement (m_displacement_node); - m_edge_softening = new ON_EdgeSoftening(m_edge_softening_node); - m_thickening = new ON_Thickening (m_thickening_node); - m_curve_piping = new ON_CurvePiping (m_curve_piping_node); - m_shutlining = new ON_Shutlining (m_shutlining_node); +void ON_MeshModifiers::CImpl::SaveToXML(ON_XMLRootNode& root) const +{ + if (nullptr != m_displacement) + m_displacement->AddChildXML(root); + + if (nullptr != m_edge_softening) + m_edge_softening->AddChildXML(root); + + if (nullptr != m_thickening) + m_thickening->AddChildXML(root); + + if (nullptr != m_curve_piping) + m_curve_piping->AddChildXML(root); + + if (nullptr != m_shut_lining) + m_shut_lining->AddChildXML(root); } ON_MeshModifiers::CImpl::~CImpl() { - delete m_displacement; - delete m_edge_softening; - delete m_thickening; - delete m_curve_piping; - delete m_shutlining; + DeleteAll(); } -ON_MeshModifiers::ON_MeshModifiers(const ON_ModelComponent& component, const wchar_t* xml) +void ON_MeshModifiers::CImpl::DeleteAll(void) { - ON_XMLRootNode node; - node.ReadFromStream(xml); - m_impl = new CImpl(node); + if (nullptr != m_displacement) + { + delete m_displacement; + m_displacement = nullptr; + } + + if (nullptr != m_edge_softening) + { + delete m_edge_softening; + m_edge_softening = nullptr; + } + + if (nullptr != m_thickening) + { + delete m_thickening; + m_thickening = nullptr; + } + + if (nullptr != m_curve_piping) + { + delete m_curve_piping; + m_curve_piping = nullptr; + } + + if (nullptr != m_shut_lining) + { + delete m_shut_lining; + m_shut_lining = nullptr; + } +} + +ON_MeshModifiers::ON_MeshModifiers() +{ + m_impl = new CImpl; } ON_MeshModifiers::~ON_MeshModifiers() @@ -1310,59 +1849,85 @@ ON_MeshModifiers::~ON_MeshModifiers() m_impl = nullptr; } -ON_Displacement& ON_MeshModifiers::Displacement(void) +void ON_MeshModifiers::LoadFromXML(const ON_XMLRootNode& node) { - return *m_impl->m_displacement; + m_impl->LoadFromXML(node); } -ON_EdgeSoftening& ON_MeshModifiers::EdgeSoftening(void) +void ON_MeshModifiers::SaveToXML(ON_XMLRootNode& node) const { - return *m_impl->m_edge_softening; + m_impl->SaveToXML(node); } -ON_Thickening& ON_MeshModifiers::Thickening(void) +const ON_MeshModifiers& ON_MeshModifiers::operator = (const ON_MeshModifiers& mm) { - return *m_impl->m_thickening; + m_impl->DeleteAll(); + + if (nullptr != mm.m_impl->m_displacement) + m_impl->m_displacement = new ON_Displacement(*mm.m_impl->m_displacement); + + if (nullptr != mm.m_impl->m_edge_softening) + m_impl->m_edge_softening = new ON_EdgeSoftening(*mm.m_impl->m_edge_softening); + + if (nullptr != mm.m_impl->m_thickening) + m_impl->m_thickening = new ON_Thickening(*mm.m_impl->m_thickening); + + if (nullptr != mm.m_impl->m_curve_piping) + m_impl->m_curve_piping = new ON_CurvePiping(*mm.m_impl->m_curve_piping); + + if (nullptr != mm.m_impl->m_shut_lining) + m_impl->m_shut_lining = new ON_ShutLining(*mm.m_impl->m_shut_lining); + + return *this; } -ON_CurvePiping& ON_MeshModifiers::CurvePiping(void) +ON_Displacement* ON_MeshModifiers::Displacement(bool allow_creation) { - return *m_impl->m_curve_piping; + if ((nullptr == m_impl->m_displacement) && allow_creation) + m_impl->m_displacement = new ON_Displacement; + + return m_impl->m_displacement; } -ON_Shutlining& ON_MeshModifiers::Shutlining(void) +ON_EdgeSoftening* ON_MeshModifiers::EdgeSoftening(bool allow_creation) { - return *m_impl->m_shutlining; + if ((nullptr == m_impl->m_edge_softening) && allow_creation) + m_impl->m_edge_softening = new ON_EdgeSoftening; + + return m_impl->m_edge_softening; } -// ON_MeshModifierCollection - -ON_MeshModifierCollection::~ON_MeshModifierCollection() +ON_Thickening* ON_MeshModifiers::Thickening(bool allow_creation) { - for (const auto& elem : m_map) - { - delete elem.second; - } + if ((nullptr == m_impl->m_thickening) && allow_creation) + m_impl->m_thickening = new ON_Thickening; - m_map.clear(); + return m_impl->m_thickening; } -ON_MeshModifiers* ON_MeshModifierCollection::Find(const ON_ModelComponent& component) +ON_CurvePiping* ON_MeshModifiers::CurvePiping(bool allow_creation) { - const auto& elem = m_map.find(component.Id()); - if (elem != m_map.end()) - return elem->second; + if ((nullptr == m_impl->m_curve_piping) && allow_creation) + m_impl->m_curve_piping = new ON_CurvePiping; - return nullptr; + return m_impl->m_curve_piping; } -bool ON_MeshModifierCollection::CreateMeshModifiersFromXML(const ONX_Model& model, int archive_3dm_version) +ON_ShutLining* ON_MeshModifiers::ShutLining(bool allow_creation) +{ + if ((nullptr == m_impl->m_shut_lining) && allow_creation) + m_impl->m_shut_lining = new ON_ShutLining; + + return m_impl->m_shut_lining; +} + +void CreateMeshModifiersFromXML(const ONX_Model& model, int archive_3dm_version) { ONX_ModelComponentIterator cit(model, ON_ModelComponent::Type::ModelGeometry); - const auto* component = cit.FirstComponent(); - for (; nullptr != component; component = cit.NextComponent()) + + for (const ON_ModelComponent* component = cit.FirstComponent(); nullptr != component; component = cit.NextComponent()) { - auto* attr = GetComponentAttributes(*component); + ON_3dmObjectAttributes* attr = GetComponentAttributes(*component); if (nullptr == attr) continue; // No attributes on component. @@ -1372,61 +1937,37 @@ bool ON_MeshModifierCollection::CreateMeshModifiersFromXML(const ONX_Model& mode if (xml.IsEmpty()) continue; // No XML found on the component's attributes. - // Create a new mesh modifiers object for this component and add it to the map. - std::pair pair(component->Id(), new ON_MeshModifiers(*component, xml)); - m_map.insert(pair); + ON_XMLRootNode root; + if (ON_XMLRootNode::ReadError != root.ReadFromStream(xml)) + { + attr->MeshModifiers().LoadFromXML(root); + } } - - return true; } -static const ON_UUID uuid_displacement_user_data +void CreateXMLFromMeshModifiers(const ONX_Model& model, int archive_3dm_version) { - 0x8224a7c4, 0x5590, 0x4ac4, { 0xa3, 0x2c, 0xde, 0x85, 0xdc, 0x2f, 0xfd, 0xae } -}; + ONX_ModelComponentIterator cit(model, ON_ModelComponent::Type::ModelGeometry); -static const ON_UUID uuid_edge_softening_user_data = -{ - 0x8cbe6160, 0x5cbd, 0x4b4d, { 0x8c, 0xd2, 0x7c, 0xe0, 0xa7, 0xc8, 0xc2, 0xd8 } -}; - -static const ON_UUID uuid_shutlining_user_data = -{ - 0x07506ebe, 0x1d69, 0x4345, { 0x9f, 0x0d, 0x2b, 0x9a, 0xa1, 0x90, 0x6e, 0xef } -}; - -static const ON_UUID uuid_curve_piping_user_data = -{ - 0x2b1a758e, 0x7cb1, 0x45ab, { 0xa5, 0xbf, 0xdf, 0xcd, 0x6d, 0x3d, 0x13, 0x6d } -}; - -static const ON_UUID uuid_thickening_user_data = -{ - 0x6aa7ccc3, 0x2721, 0x410f, { 0xaa, 0x56, 0xe8, 0xab, 0x4f, 0x3e, 0xce, 0x67 } -}; - -bool ON_MeshModifierCollection::CreateXMLFromMeshModifiers(const ONX_Model& model, int archive_3dm_version) -{ - for (const auto& elem : m_map) + for (const ON_ModelComponent* component = cit.FirstComponent(); nullptr != component; component = cit.NextComponent()) { - auto* mesh_modifiers = elem.second; - if (nullptr == mesh_modifiers) - continue; - - const auto& mgc = model.ModelGeometryComponentFromId(elem.first); - ON_ASSERT(mgc.ComponentType() == ON_ModelComponent::Type::ModelGeometry); - - // Mesh modifiers are stored on the user data of object attributes. - auto* attr = const_cast(mgc.Attributes(nullptr)); + ON_3dmObjectAttributes* attr = GetComponentAttributes(*component); if (nullptr == attr) - continue; // Should never happen because we have an item for the object. + continue; // No attributes on component. - SetMeshModifierObjectInformation(*attr, uuid_displacement_user_data, mesh_modifiers->Displacement(), archive_3dm_version); - SetMeshModifierObjectInformation(*attr, uuid_edge_softening_user_data, mesh_modifiers->EdgeSoftening(), archive_3dm_version); - SetMeshModifierObjectInformation(*attr, uuid_thickening_user_data, mesh_modifiers->Thickening(), archive_3dm_version); - SetMeshModifierObjectInformation(*attr, uuid_curve_piping_user_data, mesh_modifiers->CurvePiping(), archive_3dm_version); - SetMeshModifierObjectInformation(*attr, uuid_shutlining_user_data, mesh_modifiers->Shutlining(), archive_3dm_version); + // Get all the XML for all the mesh modifiers under one root node. This is just for convenience + // and it's not how the XML will appear in the 3dm file because it's going to be distributed to + // separate user data objects by SetMeshModifierObjectInformation(). + ON_MeshModifiers& mm = attr->MeshModifiers(); + ON_XMLRootNode root; + mm.SaveToXML(root); + + // 'root' will only contain XML for the mesh modifiers that exist (which may be none). + // If there are none, no user data will be added to the attributes by the following. + SetMeshModifierObjectInformation(*attr, mm.Displacement(), root, archive_3dm_version, ON_DISPLACEMENT_ROOT); + SetMeshModifierObjectInformation(*attr, mm.EdgeSoftening(), root, archive_3dm_version, ON_EDGE_SOFTENING_ROOT); + SetMeshModifierObjectInformation(*attr, mm.Thickening(), root, archive_3dm_version, ON_THICKENING_ROOT); + SetMeshModifierObjectInformation(*attr, mm.CurvePiping(), root, archive_3dm_version, ON_CURVE_PIPING_ROOT); + SetMeshModifierObjectInformation(*attr, mm.ShutLining(), root, archive_3dm_version, ON_SHUTLINING_ROOT); } - - return true; } diff --git a/opennurbs_mesh_modifiers.h b/opennurbs_mesh_modifiers.h index 6ff1acc8..e5d58bd4 100644 --- a/opennurbs_mesh_modifiers.h +++ b/opennurbs_mesh_modifiers.h @@ -16,26 +16,85 @@ class ON_CLASS ON_MeshModifier { +public: + // Returns the plug-in id of the 'Displacement' plug-in which implements all the mesh modifiers. + static ON_UUID PlugInId(void); + public: ON_MeshModifier(); - ON_MeshModifier(ON_XMLNode& model_node); + ON_MeshModifier(const ON_XMLNode& node); ON_MeshModifier(const ON_MeshModifier& mm) = delete; virtual ~ON_MeshModifier(); const ON_MeshModifier& operator = (const ON_MeshModifier&) = delete; - ON_wString XML(void) const; + // Return the unique identifier of this mesh modifier. + virtual ON_UUID Uuid(void) const = 0; + +public: // For internal use only. + virtual ON_XMLNode* AddChildXML(ON_XMLRootNode& root) const; protected: class CImpl; CImpl* m_impl; }; +//////////////////////////////////////////////////////////////// +// +// Displacement +// +//////////////////////////////////////////////////////////////// + +#define ON_DISPLACEMENT_ROOT L"new-displacement-object-data" + #define ON_DISPLACEMENT_ON L"on" + #define ON_DISPLACEMENT_CHANNEL L"channel" + #define ON_DISPLACEMENT_BLACK_POINT L"black-point" + #define ON_DISPLACEMENT_WHITE_POINT L"white-point" + #define ON_DISPLACEMENT_SWEEP_PITCH L"sweep-pitch" + #define ON_DISPLACEMENT_REFINE_STEPS L"refine-steps" + #define ON_DISPLACEMENT_REFINE_SENSITIVITY L"refine-sensitivity" + #define ON_DISPLACEMENT_TEXTURE L"texture" + #define ON_DISPLACEMENT_FACE_COUNT_LIMIT_ENABLED L"face-count-limit-enabled" + #define ON_DISPLACEMENT_FACE_COUNT_LIMIT L"face-count-limit" + #define ON_DISPLACEMENT_POST_WELD_ANGLE L"post-weld-angle" + #define ON_DISPLACEMENT_MESH_MEMORY_LIMIT L"mesh-memory-limit" + #define ON_DISPLACEMENT_FAIRING_ENABLED L"fairing-enabled" + #define ON_DISPLACEMENT_FAIRING_AMOUNT L"fairing-amount" + #define ON_DISPLACEMENT_SWEEP_RES_FORMULA L"sweep-res-formula" + #define ON_DISPLACEMENT_SUB_OBJECT_COUNT L"sub-object-count" + #define ON_DISPLACEMENT_SUB L"sub" + #define ON_DISPLACEMENT_SUB_INDEX L"sub-index" + #define ON_DISPLACEMENT_SUB_ON L"sub-on" + #define ON_DISPLACEMENT_SUB_TEXTURE L"sub-texture" + #define ON_DISPLACEMENT_SUB_CHANNEL L"sub-channel" + #define ON_DISPLACEMENT_SUB_BLACK_POINT L"sub-black-point" + #define ON_DISPLACEMENT_SUB_WHITE_POINT L"sub-white-point" + +class ON_CLASS ON_DisplacementUserData : public ON_XMLUserData +{ +private: + ON_OBJECT_DECLARE(ON_DisplacementUserData); + +public: + ON_DisplacementUserData(); + ON_DisplacementUserData(const ON_DisplacementUserData& ud); + + static ON_UUID Uuid(void); + + const ON_DisplacementUserData& operator = (const ON_DisplacementUserData& ud); + + virtual bool GetDescription(ON_wString& s) override; + virtual void SetToDefaults(void) const override; + virtual void ReportVersionError(void) const override; + virtual bool Transform(const ON_Xform& xform) override; + virtual bool Read(ON_BinaryArchive&) override; +}; + class ON_CLASS ON_Displacement : public ON_MeshModifier { public: ON_Displacement(); - ON_Displacement(ON_XMLNode& model_node); + ON_Displacement(const ON_XMLNode& node); ON_Displacement(const ON_Displacement& dsp); ~ON_Displacement(); @@ -95,7 +154,7 @@ public: class ON_CLASS SubItem final { public: - SubItem(ON_XMLNode& sub_node); + SubItem(const ON_XMLNode& sub_node); SubItem(const SubItem&) = delete; ~SubItem(); @@ -129,6 +188,9 @@ public: double WhitePoint(void) const; void SetWhitePoint(double w); + // For internal use only. + void ToXML(ON_XMLNode& node) const; + private: class CImpl; CImpl* m_impl; @@ -152,16 +214,70 @@ public: SubItem* FindSubItem(const int index) const; SubItemIterator GetSubItemIterator(void) const; + virtual ON_UUID Uuid(void) const override; + + class ON_CLASS Defaults final + { + public: + static int RefineStepCount(void); + static int FairingAmount(void); + static int FaceLimit(void); + static int ChannelNumber(void); + static int MeshMemoryLimit(void); + static double BlackPoint(void); + static double WhitePoint(void); + static double SweepPitch(void); + static double RefineSensitivity(void); + static double PostWeldAngle(void); + static double AbsoluteTolerance(void); + static SweepResolutionFormulas SweepResolutionFormula(void); + }; + +public: // For internal use only. + virtual ON_XMLNode* AddChildXML(ON_XMLRootNode& root) const override; + private: class CImplDSP; CImplDSP* m_impl_dsp; }; +//////////////////////////////////////////////////////////////// +// +// Edge Softening +// +//////////////////////////////////////////////////////////////// + +#define ON_EDGE_SOFTENING_ROOT L"edge-softening-object-data" + #define ON_EDGE_SOFTENING_ON L"on" + #define ON_EDGE_SOFTENING_SOFTENING L"softening" + #define ON_EDGE_SOFTENING_CHAMFER L"chamfer" + #define ON_EDGE_SOFTENING_UNWELD L"unweld" + #define ON_EDGE_SOFTENING_FORCE_SOFTENING L"force-softening" + #define ON_EDGE_SOFTENING_EDGE_THRESHOLD L"edge-threshold" + +class ON_CLASS ON_EdgeSofteningUserData : public ON_XMLUserData +{ +private: + ON_OBJECT_DECLARE(ON_EdgeSofteningUserData); + +public: + ON_EdgeSofteningUserData(); + ON_EdgeSofteningUserData(const ON_EdgeSofteningUserData& ud); + + static ON_UUID Uuid(void); + + const ON_EdgeSofteningUserData& operator = (const ON_EdgeSofteningUserData& ud); + + virtual bool GetDescription(ON_wString& s) override; + virtual void SetToDefaults(void) const override; + virtual void ReportVersionError(void) const override; +}; + class ON_CLASS ON_EdgeSoftening : public ON_MeshModifier { public: ON_EdgeSoftening(); - ON_EdgeSoftening(ON_XMLNode& model_node); + ON_EdgeSoftening(const ON_XMLNode& node); ON_EdgeSoftening(const ON_EdgeSoftening& es); const ON_EdgeSoftening& operator = (const ON_EdgeSoftening& es); @@ -193,13 +309,57 @@ public: // Specifies whether to soften edges despite too large a radius. bool ForceSoftening(void) const; void SetForceSoftening(bool b); + + virtual ON_UUID Uuid(void) const override; + + class ON_CLASS Defaults final + { + public: + static bool Chamfer(void); + static bool Faceted(void); + static bool ForceSoftening(void); + static double Softening(void); + static double EdgeAngleThreshold(void); + }; +}; + +//////////////////////////////////////////////////////////////// +// +// Thickening +// +//////////////////////////////////////////////////////////////// + +#define ON_THICKENING_ROOT L"thickening-object-data" + #define ON_THICKENING_ON L"on" + #define ON_THICKENING_DISTANCE L"distance" + #define ON_THICKENING_SOLID L"solid" + #define ON_THICKENING_BOTH_SIDES L"both-sides" + #define ON_THICKENING_OFFSET_ONLY L"offset-only" + +class ON_CLASS ON_ThickeningUserData : public ON_XMLUserData +{ +private: + ON_OBJECT_DECLARE(ON_ThickeningUserData); + +public: + ON_ThickeningUserData(); + ON_ThickeningUserData(const ON_ThickeningUserData& ud); + + static ON_UUID Uuid(void); + + const ON_ThickeningUserData& operator = (const ON_ThickeningUserData& ud); + + virtual void SetToDefaults(void) const; + virtual bool GetDescription(ON_wString& s); + virtual void ReportVersionError(void) const; + virtual bool Transform(const ON_Xform& xform); }; class ON_CLASS ON_Thickening : public ON_MeshModifier { public: ON_Thickening(); - ON_Thickening(ON_XMLNode& model_node); + ON_Thickening(const ON_XMLNode& node); ON_Thickening(const ON_Thickening& t); const ON_Thickening& operator = (const ON_Thickening& t); @@ -222,13 +382,55 @@ public: bool BothSides(void) const; void SetBothSides(bool b); + + virtual ON_UUID Uuid(void) const override; + + class ON_CLASS Defaults final + { + public: + static bool Solid(void); + static bool BothSides(void); + static bool OffsetOnly(void); + static double Distance(void); + }; +}; + +#define ON_CURVE_PIPING_ROOT L"curve-piping-object-data" + #define ON_CURVE_PIPING_ON L"on" + #define ON_CURVE_PIPING_SEGMENTS L"segments" + #define ON_CURVE_PIPING_RADIUS L"radius" + #define ON_CURVE_PIPING_ACCURACY L"accuracy" + #define ON_CURVE_PIPING_WELD L"weld" // 'Weld' is a legacy name. The real name is 'Faceted' but this is the INVERSE of weld. + #define ON_CURVE_PIPING_CAP_TYPE L"cap-type" + #define ON_CURVE_PIPING_NONE L"none" + #define ON_CURVE_PIPING_FLAT L"flat" + #define ON_CURVE_PIPING_BOX L"box" + #define ON_CURVE_PIPING_DOME L"dome" + +class ON_CLASS ON_CurvePipingUserData : public ON_XMLUserData +{ +private: + ON_OBJECT_DECLARE(ON_CurvePipingUserData); + +public: + ON_CurvePipingUserData(); + ON_CurvePipingUserData(const ON_CurvePipingUserData& ud); + + static ON_UUID Uuid(void); + + const ON_CurvePipingUserData& operator = (const ON_CurvePipingUserData& ud); + + virtual void SetToDefaults(void) const; + virtual bool GetDescription(ON_wString& s); + virtual void ReportVersionError(void) const; + virtual bool Transform(const ON_Xform& xform); }; class ON_CLASS ON_CurvePiping : public ON_MeshModifier { public: ON_CurvePiping(); - ON_CurvePiping(ON_XMLNode& model_node); + ON_CurvePiping(const ON_XMLNode& node); ON_CurvePiping(const ON_CurvePiping& cp); const ON_CurvePiping& operator = (const ON_CurvePiping& cp); @@ -267,20 +469,64 @@ public: // The type of cap to be created at the ends of the pipe. CapTypes CapType(void) const; void SetCapType(CapTypes ct); + + virtual ON_UUID Uuid(void) const override; + + class ON_CLASS Defaults final + { + public: + static bool Faceted(void); + static int Segments(void); + static int Accuracy(void); + static double Radius(void); + static CapTypes CapType(void); + }; }; -class ON_CLASS ON_Shutlining : public ON_MeshModifier +#define ON_SHUTLINING_ROOT L"shut-lining-object-data" + #define ON_SHUTLINING_ON L"on" + #define ON_SHUTLINING_FACETED L"faceted" + #define ON_SHUTLINING_AUTO_UPDATE L"auto-update" + #define ON_SHUTLINING_FORCE_UPDATE L"force-update" + #define ON_SHUTLINING_CURVE L"curve" + #define ON_SHUTLINING_CURVE_UUID L"uuid" + #define ON_SHUTLINING_CURVE_ENABLED L"enabled" + #define ON_SHUTLINING_CURVE_RADIUS L"radius" + #define ON_SHUTLINING_CURVE_PROFILE L"profile" + #define ON_SHUTLINING_CURVE_PULL L"pull" + #define ON_SHUTLINING_CURVE_IS_BUMP L"is-bump" + +class ON_CLASS ON_ShutLiningUserData : public ON_XMLUserData +{ +private: + ON_OBJECT_DECLARE(ON_ShutLiningUserData); + +public: + ON_ShutLiningUserData(); + ON_ShutLiningUserData(const ON_ShutLiningUserData& ud); + + static ON_UUID Uuid(void); + + const ON_ShutLiningUserData& operator = (const ON_ShutLiningUserData& ud); + + virtual void SetToDefaults(void) const override; + virtual bool GetDescription(ON_wString& s) override; + virtual void ReportVersionError(void) const override; + virtual bool Transform(const ON_Xform& xform) override; +}; + +class ON_CLASS ON_ShutLining : public ON_MeshModifier { public: - ON_Shutlining(); - ON_Shutlining(ON_XMLNode& model_node); - ON_Shutlining(const ON_Shutlining& sl); - virtual ~ON_Shutlining(); + ON_ShutLining(); + ON_ShutLining(const ON_XMLNode& node); + ON_ShutLining(const ON_ShutLining& sl); + virtual ~ON_ShutLining(); - const ON_Shutlining& operator = (const ON_Shutlining& sl); + const ON_ShutLining& operator = (const ON_ShutLining& sl); - bool operator == (const ON_Shutlining& sl) const; - bool operator != (const ON_Shutlining& sl) const; + bool operator == (const ON_ShutLining& sl) const; + bool operator != (const ON_ShutLining& sl) const; // Specifies whether the feature is enabled or not. bool On(void) const; @@ -301,7 +547,7 @@ public: class ON_CLASS Curve final { public: - Curve(ON_XMLNode& curve_node); + Curve(const ON_XMLNode& curve_node); Curve(const Curve&) = delete; ~Curve(); @@ -328,6 +574,19 @@ public: bool IsBump(void) const; void SetIsBump(bool b); + class ON_CLASS Defaults final + { + public: + static bool Enabled(void); + static bool Pull(void); + static bool IsBump(void); + static int Profile(void); + static double Radius(void); + }; + + // For internal use only. + void ToXML(ON_XMLNode& node) const; + private: class CImpl; CImpl* m_impl; @@ -336,7 +595,7 @@ public: class ON_CLASS CurveIterator final { public: - CurveIterator(const ON_Shutlining& sl); + CurveIterator(const ON_ShutLining& sl); ~CurveIterator(); Curve* Next(void); @@ -360,6 +619,20 @@ public: // Gets an iterator for iterating over all the curves on the shutlining. CurveIterator GetCurveIterator(void) const; + virtual ON_UUID Uuid(void) const override; + + class ON_CLASS Defaults final + { + public: + static bool Faceted(void); + static bool AutoUpdate(void); + static bool ForceUpdate(void); + static double Tolerance(void); + }; + +public: // For internal use only. + virtual ON_XMLNode* AddChildXML(ON_XMLRootNode& root) const override; + private: class CImplSL; CImplSL* m_impl_sl; @@ -368,29 +641,43 @@ private: class ON_CLASS ON_MeshModifiers final { public: - ON_MeshModifiers(const ON_ModelComponent& component, const wchar_t* xml); + ON_MeshModifiers(); ON_MeshModifiers(const ON_MeshModifiers&) = delete; ~ON_MeshModifiers(); - const ON_MeshModifiers& operator = (const ON_MeshModifiers&) = delete; - bool operator == (const ON_MeshModifiers&) const = delete; bool operator != (const ON_MeshModifiers&) const = delete; + const ON_MeshModifiers& operator = (const ON_MeshModifiers& mm); + // Get an object that provides access to displacement information. - ON_Displacement& Displacement(void); + // If there is no displacement information and 'allow_creation' is false, the method returns null. + // If there is no displacement information and 'allow_creation' is true, a default displacement object is created. + ON_Displacement* Displacement(bool allow_creation=false); // Get an object that provides access to edge softening information. - ON_EdgeSoftening& EdgeSoftening(void); + // If there is no edge softening information and 'allow_creation' is false, the method returns null. + // If there is no edge softening information and 'allow_creation' is true, a default edge softening object is created. + ON_EdgeSoftening* EdgeSoftening(bool allow_creation=false); // Get an object that provides access to thickening information. - ON_Thickening& Thickening(void); + // If there is no thickening information and 'allow_creation' is false, the method returns null. + // If there is no thickening information and 'allow_creation' is true, a default thickening object is created. + ON_Thickening* Thickening(bool allow_creation=false); // Get an object that provides access to curve piping information. - ON_CurvePiping& CurvePiping(void); + // If there is no curve piping information and 'allow_creation' is false, the method returns null. + // If there is no curve piping information and 'allow_creation' is true, a default curve piping object is created. + ON_CurvePiping* CurvePiping(bool allow_creation=false); - // Get an object that provides access to shutlining information. - ON_Shutlining& Shutlining(void); + // Get an object that provides access to shut-lining information. + // If there is no shut-lining information and 'allow_creation' is false, the method returns null. + // If there is no shut-lining information and 'allow_creation' is true, a default shut-lining object is created. + ON_ShutLining* ShutLining(bool allow_creation=false); + +public: // For internal use only. + void LoadFromXML(const ON_XMLRootNode&); + void SaveToXML(ON_XMLRootNode&) const; private: class CImpl; diff --git a/opennurbs_nurbscurve.cpp b/opennurbs_nurbscurve.cpp index 6c6756f6..7a56c3aa 100644 --- a/opennurbs_nurbscurve.cpp +++ b/opennurbs_nurbscurve.cpp @@ -3243,8 +3243,9 @@ bool ON_NurbsCurve::Split( i = left->m_cv_count - left->m_order; //23 April 2015 - Chuck - maintain stride + // 31 Aug 2022 GBA RH69916 split at split_t not t. Splitting at t produces a gap that can't be right. //ON_EvaluateNurbsDeBoor( cvdim, m_order, cvdim, left->CV(i), left->m_knot + i, -1, 0.0, t ); - ON_EvaluateNurbsDeBoor( cvdim, m_order, cv_stride, left->CV(i), left->m_knot + i, -1, 0.0, t ); + ON_EvaluateNurbsDeBoor( cvdim, m_order, cv_stride, left->CV(i), left->m_knot + i, -1, 0.0, split_t); for ( i = left->m_cv_count-1; i < ON_KnotCount(left->m_order,left->m_cv_count); i++ ) left->m_knot[i] = t; left->ClampEnd(2); // 26 June 2003 Dale Lear @@ -3252,8 +3253,9 @@ bool ON_NurbsCurve::Split( // trim left end of right NURBS //23 April 2015 - Chuck - maintain stride + // 31 Aug 2022 GBA RH69916 split at split_t not t. Splitting at t produces a gap that can't be right. //ON_EvaluateNurbsDeBoor( cvdim, m_order, cvdim, right->m_cv, right->m_knot, +1, 0.0, t ); - ON_EvaluateNurbsDeBoor( cvdim, m_order, cv_stride, right->m_cv, right->m_knot, +1, 0.0, t ); + ON_EvaluateNurbsDeBoor( cvdim, m_order, cv_stride, right->m_cv, right->m_knot, +1, 0.0, split_t); for ( i = 0; i <= right->m_order-2; i++ ) right->m_knot[i] = t; right->ClampEnd(2); // 26 June 2003 Dale Lear diff --git a/opennurbs_polylinecurve.cpp b/opennurbs_polylinecurve.cpp index 1c0d2ba6..00453fda 100644 --- a/opennurbs_polylinecurve.cpp +++ b/opennurbs_polylinecurve.cpp @@ -1365,3 +1365,19 @@ bool ON_PolylineCurve::GetNurbFormParameterFromCurveParameter( *nurbs_t = curve_t; return true; } + +void ON_PolylineCurve::SetArcLengthParameterization(double tolerance) +{ + double d, mind = tolerance; + m_t[0] = 0; + const int count = m_pline.Count(); + for (int i = 1; i < count; i++) + { + d = (m_pline[i] - m_pline[i - 1]).Length(); + if (d < mind) + d = mind; + if (d < fabs(m_t[i - 1]) * 1e-5) + d = fabs(m_t[i - 1]) * 1e-5; + m_t[i] = m_t[i - 1] + d; + } +} diff --git a/opennurbs_polylinecurve.h b/opennurbs_polylinecurve.h index ce0eb98d..efea3364 100644 --- a/opennurbs_polylinecurve.h +++ b/opennurbs_polylinecurve.h @@ -527,6 +527,15 @@ public: bool Append( const ON_PolylineCurve& ); + /* + Description: + Sets the polyline curve to use arc length parameterization + for higher quality geometry. + Parameters: + tolerance - [in] Minimum distance tolerance. + */ + void SetArcLengthParameterization(double tolerance); + ///////////////////////////////////////////////////////////////// // Interface public: diff --git a/opennurbs_post_effects.cpp b/opennurbs_post_effects.cpp index d905d231..0609344e 100644 --- a/opennurbs_post_effects.cpp +++ b/opennurbs_post_effects.cpp @@ -183,6 +183,10 @@ bool ON_PostEffect::SetParameter(const wchar_t* param_name, const ON_XMLVariant& ON_XMLParameters p(*node); + ON_XMLVariant current_value; + if (!p.GetParam(param_name, current_value)) + return false; // If you can't get it, you can't set it. + if (!p.SetParam(param_name, param_value)) return false; diff --git a/opennurbs_public.vcxproj b/opennurbs_public.vcxproj index 0b44779b..bd2cc0b0 100644 --- a/opennurbs_public.vcxproj +++ b/opennurbs_public.vcxproj @@ -144,6 +144,7 @@ + @@ -163,7 +164,6 @@ - @@ -310,6 +310,7 @@ + @@ -336,7 +337,6 @@ - diff --git a/opennurbs_public.xcodeproj/project.pbxproj b/opennurbs_public.xcodeproj/project.pbxproj index 79fbe4b7..7f46659b 100644 --- a/opennurbs_public.xcodeproj/project.pbxproj +++ b/opennurbs_public.xcodeproj/project.pbxproj @@ -339,7 +339,6 @@ 1DC319EC1ED6534E00DE6D26 /* opennurbs_zlib_memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DC319921ED6534E00DE6D26 /* opennurbs_zlib_memory.cpp */; }; 1DC319ED1ED6534E00DE6D26 /* opennurbs_zlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DC319931ED6534E00DE6D26 /* opennurbs_zlib.cpp */; }; 1DC319EE1ED6534E00DE6D26 /* opennurbs_zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DC319941ED6534E00DE6D26 /* opennurbs_zlib.h */; }; - 99D80C50288871F300E95705 /* opennurbs_current_environment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99D80C4F288871F300E95705 /* opennurbs_current_environment.cpp */; }; 99D80C522888720000E95705 /* opennurbs_decals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99D80C512888720000E95705 /* opennurbs_decals.cpp */; }; 99D80C542888721000E95705 /* opennurbs_dithering.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99D80C532888721000E95705 /* opennurbs_dithering.cpp */; }; 99D80C562888722200E95705 /* opennurbs_ground_plane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99D80C552888722200E95705 /* opennurbs_ground_plane.cpp */; }; @@ -356,7 +355,6 @@ 99D80C77288872CF00E95705 /* opennurbs_render_channels.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D80C6A288872CE00E95705 /* opennurbs_render_channels.h */; }; 99D80C78288872CF00E95705 /* opennurbs_ground_plane.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D80C6B288872CE00E95705 /* opennurbs_ground_plane.h */; }; 99D80C79288872CF00E95705 /* opennurbs_safe_frame.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D80C6C288872CE00E95705 /* opennurbs_safe_frame.h */; }; - 99D80C7A288872CF00E95705 /* opennurbs_current_environment.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D80C6D288872CE00E95705 /* opennurbs_current_environment.h */; }; 99D80C7B288872CF00E95705 /* opennurbs_sun.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D80C6E288872CE00E95705 /* opennurbs_sun.h */; }; 99D80C7C288872CF00E95705 /* opennurbs_decals.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D80C6F288872CE00E95705 /* opennurbs_decals.h */; }; 99D80C7D288872CF00E95705 /* opennurbs_mesh_modifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D80C70288872CE00E95705 /* opennurbs_mesh_modifiers.h */; }; @@ -703,7 +701,6 @@ 1DC319921ED6534E00DE6D26 /* opennurbs_zlib_memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_zlib_memory.cpp; sourceTree = ""; }; 1DC319931ED6534E00DE6D26 /* opennurbs_zlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_zlib.cpp; sourceTree = ""; }; 1DC319941ED6534E00DE6D26 /* opennurbs_zlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_zlib.h; sourceTree = ""; }; - 99D80C4F288871F300E95705 /* opennurbs_current_environment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_current_environment.cpp; sourceTree = ""; }; 99D80C512888720000E95705 /* opennurbs_decals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_decals.cpp; sourceTree = ""; }; 99D80C532888721000E95705 /* opennurbs_dithering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_dithering.cpp; sourceTree = ""; }; 99D80C552888722200E95705 /* opennurbs_ground_plane.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opennurbs_ground_plane.cpp; sourceTree = ""; }; @@ -720,7 +717,6 @@ 99D80C6A288872CE00E95705 /* opennurbs_render_channels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_render_channels.h; sourceTree = ""; }; 99D80C6B288872CE00E95705 /* opennurbs_ground_plane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_ground_plane.h; sourceTree = ""; }; 99D80C6C288872CE00E95705 /* opennurbs_safe_frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_safe_frame.h; sourceTree = ""; }; - 99D80C6D288872CE00E95705 /* opennurbs_current_environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_current_environment.h; sourceTree = ""; }; 99D80C6E288872CE00E95705 /* opennurbs_sun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_sun.h; sourceTree = ""; }; 99D80C6F288872CE00E95705 /* opennurbs_decals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_decals.h; sourceTree = ""; }; 99D80C70288872CE00E95705 /* opennurbs_mesh_modifiers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opennurbs_mesh_modifiers.h; sourceTree = ""; }; @@ -792,7 +788,6 @@ 1DC317951ED652B700DE6D26 /* opennurbs_cone.h */, 1DC317961ED652B700DE6D26 /* opennurbs_cpp_base.h */, 1DC317981ED652B700DE6D26 /* opennurbs_crc.h */, - 99D80C6D288872CE00E95705 /* opennurbs_current_environment.h */, 1DC3179A1ED652B700DE6D26 /* opennurbs_curve.h */, 1DC3179C1ED652B700DE6D26 /* opennurbs_curveonsurface.h */, 1DC3179E1ED652B800DE6D26 /* opennurbs_curveproxy.h */, @@ -972,7 +967,6 @@ 1DC317921ED652B700DE6D26 /* opennurbs_compstat.cpp */, 1DC317941ED652B700DE6D26 /* opennurbs_cone.cpp */, 1DC317971ED652B700DE6D26 /* opennurbs_crc.cpp */, - 99D80C4F288871F300E95705 /* opennurbs_current_environment.cpp */, 1DC317991ED652B700DE6D26 /* opennurbs_curve.cpp */, 1DC3179B1ED652B700DE6D26 /* opennurbs_curveonsurface.cpp */, 1DC3179D1ED652B700DE6D26 /* opennurbs_curveproxy.cpp */, @@ -1215,7 +1209,6 @@ 1DC318E81ED652F800DE6D26 /* opennurbs_nurbscurve.h in Headers */, 1DC318251ED652B800DE6D26 /* opennurbs_fpoint.h in Headers */, 1DC317D01ED652B800DE6D26 /* opennurbs_annotationbase.h in Headers */, - 99D80C7A288872CF00E95705 /* opennurbs_current_environment.h in Headers */, 1DC318BE1ED652F800DE6D26 /* opennurbs_knot.h in Headers */, 99D80C78288872CF00E95705 /* opennurbs_ground_plane.h in Headers */, 1DC3199F1ED6534E00DE6D26 /* opennurbs_string.h in Headers */, @@ -1496,7 +1489,6 @@ 1DC318E91ED652F800DE6D26 /* opennurbs_nurbssurface.cpp in Sources */, 1DBFBF3A1EDF3092005B50AF /* opennurbs_public_memory.cpp in Sources */, 1DC319C91ED6534E00DE6D26 /* opennurbs_textiterator.cpp in Sources */, - 99D80C50288871F300E95705 /* opennurbs_current_environment.cpp in Sources */, 1DC317CF1ED652B800DE6D26 /* opennurbs_annotationbase.cpp in Sources */, 1DC318AE1ED652F800DE6D26 /* opennurbs_instance.cpp in Sources */, 1DC318E41ED652F800DE6D26 /* opennurbs_model_geometry.cpp in Sources */, diff --git a/opennurbs_public_staticlib.vcxproj b/opennurbs_public_staticlib.vcxproj index e7bc7621..677ebd46 100644 --- a/opennurbs_public_staticlib.vcxproj +++ b/opennurbs_public_staticlib.vcxproj @@ -145,6 +145,7 @@ + @@ -163,7 +164,6 @@ - @@ -310,6 +310,7 @@ + @@ -336,7 +337,6 @@ - diff --git a/opennurbs_public_version.h b/opennurbs_public_version.h index bc15a66a..9fa6e4c2 100644 --- a/opennurbs_public_version.h +++ b/opennurbs_public_version.h @@ -14,10 +14,10 @@ // first step in each build. // #define RMA_VERSION_YEAR 2022 -#define RMA_VERSION_MONTH 8 -#define RMA_VERSION_DATE 12 +#define RMA_VERSION_MONTH 9 +#define RMA_VERSION_DATE 6 #define RMA_VERSION_HOUR 10 -#define RMA_VERSION_MINUTE 9 +#define RMA_VERSION_MINUTE 45 //////////////////////////////////////////////////////////////// // @@ -35,8 +35,8 @@ // 3 = build system release build #define RMA_VERSION_BRANCH 0 -#define VERSION_WITH_COMMAS 8,0,22224,10090 -#define VERSION_WITH_PERIODS 8.0.22224.10090 +#define VERSION_WITH_COMMAS 8,0,22249,10450 +#define VERSION_WITH_PERIODS 8.0.22249.10450 #define COPYRIGHT "Copyright (C) 1993-2022, 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.22224.10090" -#define RMA_VERSION_WITH_PERIODS_WSTRING L"8.0.22224.10090" +#define RMA_VERSION_WITH_PERIODS_STRING "8.0.22249.10450" +#define RMA_VERSION_WITH_PERIODS_WSTRING L"8.0.22249.10450" diff --git a/opennurbs_render_channels.cpp b/opennurbs_render_channels.cpp index 3f05d730..31bf2b25 100644 --- a/opennurbs_render_channels.cpp +++ b/opennurbs_render_channels.cpp @@ -116,8 +116,8 @@ bool ON_RenderChannels::operator == (const ON_RenderChannels& rch) return false; ON_ClassArray a, b; - const auto s1 = GetSortedCustomListAsString(*this); - const auto s2 = GetSortedCustomListAsString(rch); + const ON_wString s1 = GetSortedCustomListAsString(*this); + const ON_wString s2 = GetSortedCustomListAsString(rch); if (s1 != s2) return false; @@ -133,7 +133,7 @@ ON_RenderChannels::Modes ON_RenderChannels::Mode(void) const { auto mode = Modes::Automatic; - const auto s = m_impl->GetParameter(XMLPath(), ON_RDK_RCH_MODE, ON_RDK_RCH_MODE_AUTOMATIC).AsString(); + const ON_wString s = m_impl->GetParameter(XMLPath(), ON_RDK_RCH_MODE, ON_RDK_RCH_MODE_AUTOMATIC).AsString(); if (ON_RDK_RCH_MODE_CUSTOM == s) mode = Modes::Custom; @@ -151,8 +151,8 @@ void ON_RenderChannels::SetMode(Modes m) void ON_RenderChannels::GetCustomList(ON_SimpleArray& chan) const { - auto s = m_impl->GetParameter(XMLPath(), ON_RDK_RCH_LIST, false).AsString(); - const auto len = s.Length(); + ON_wString s = m_impl->GetParameter(XMLPath(), ON_RDK_RCH_LIST, false).AsString(); + const int len = s.Length(); if (len == 0) return; @@ -162,7 +162,7 @@ void ON_RenderChannels::GetCustomList(ON_SimpleArray& chan) const int pos = -1; while ((pos = s.Find(L";")) >= 0) { - const auto uuid = ON_UuidFromString(s.Left(pos)); + const ON_UUID uuid = ON_UuidFromString(s.Left(pos)); chan.Append(uuid); s = s.Mid(pos+1); } diff --git a/opennurbs_render_content.cpp b/opennurbs_render_content.cpp index 54d3a36a..d54b6c22 100644 --- a/opennurbs_render_content.cpp +++ b/opennurbs_render_content.cpp @@ -147,7 +147,7 @@ static void ON_ConstructXform(double scale_x, double scale_y, double scale_z, { // All angles in degrees. - const auto S = ON_Xform::DiagonalTransformation(scale_x, scale_y, scale_z); + const ON_Xform S = ON_Xform::DiagonalTransformation(scale_x, scale_y, scale_z); ON_Xform R; R.Rotation(ON_RadiansFromDegrees(angle_x), ON_3dVector::XAxis, ON_3dPoint::Origin); @@ -304,7 +304,7 @@ ON__UINT32 ON_Texture_CRC(const ON_Texture& tex) #ifdef ON_RUNTIME_WIN file.MakeLower(); #endif - auto crc = file.DataCRC(0); + ON__UINT32 crc = file.DataCRC(0); crc = ON_CRC32(crc, sizeof(tex.m_mapping_channel_id), &tex.m_mapping_channel_id); @@ -322,7 +322,7 @@ ON__UINT32 ON_Texture_CRC(const ON_Texture& tex) crc = ON_CRC32(crc, sizeof(tex.m_blend_order), &tex.m_blend_order); - const auto amount = int(tex.m_blend_constant_A * 100.0) / 100.0; + const double amount = int(tex.m_blend_constant_A * 100.0) / 100.0; crc = ON_CRC32(crc, sizeof(amount), &amount); crc = ON_CRC32(crc, sizeof(tex.m_bump_scale), &tex.m_bump_scale); @@ -525,7 +525,7 @@ ON_XMLVariant ON_RenderContent::CImpl::GetPropertyValue(const wchar_t* name) con ON_XMLVariant v; - const auto* pProp = m_node.GetNamedProperty(name); + const ON_XMLProperty* pProp = m_node.GetNamedProperty(name); if (nullptr != pProp) { v = pProp->GetValue(); @@ -549,7 +549,7 @@ void ON_RenderContent::CImpl::InternalSetPropertyValue(const wchar_t* name, cons // - the environment node // - the texture node - auto* pProp = m_node.GetNamedProperty(name); + ON_XMLProperty* pProp = m_node.GetNamedProperty(name); if (nullptr != pProp) { pProp->SetValue(value); @@ -575,12 +575,12 @@ void ON_RenderContent::CImpl::SetXMLNode(const ON_XMLNode& node) while (nullptr != (child_node = it.GetNextChild())) { // See if the child node is a content node. - const auto& name = child_node->TagName(); + const ON_wString& name = child_node->TagName(); if ((ON_KIND_MATERIAL == name) || (ON_KIND_ENVIRONMENT == name) || (ON_KIND_TEXTURE == name)) { // Yes, so we are going to add a new render content to this hierarchy (recursively) // and remove this child node from the copy of the XML node. - auto* child_rc = NewRenderContentFromNode(*child_node); + ON_RenderContent* child_rc = NewRenderContentFromNode(*child_node); if (nullptr != child_rc) { // Add the new content as a child of this content. @@ -612,7 +612,7 @@ bool ON_RenderContent::CImpl::AddChild(ON_RenderContent& child) } else { - auto* last_child = FindLastChild(); + ON_RenderContent* last_child = FindLastChild(); if (nullptr == last_child) return false; @@ -632,7 +632,7 @@ void ON_RenderContent::CImpl::DeleteAllChildren(void) if (nullptr == m_first_child) return; - auto* child_rc = m_first_child; + ON_RenderContent* child_rc = m_first_child; while (nullptr != child_rc) { auto* delete_rc = child_rc; @@ -647,7 +647,7 @@ ON_RenderContent* ON_RenderContent::CImpl::FindLastChild(void) const { ON_RenderContent* result = nullptr; - auto* candidate = m_first_child; + ON_RenderContent* candidate = m_first_child; while (nullptr != candidate) { result = candidate; @@ -661,7 +661,7 @@ ON_RenderContent* ON_RenderContent::CImpl::FindPrevSibling(ON_RenderContent* chi { if (child != m_first_child) { - auto* candidate = m_first_child; + ON_RenderContent* candidate = m_first_child; while (nullptr != candidate) { if (child == candidate->m_impl->m_next_sibling) @@ -702,7 +702,7 @@ bool ON_RenderContent::CImpl::ChangeChild(ON_RenderContent* old_child, ON_Render } else { - const auto* prev_sibling = FindPrevSibling(old_child); + const ON_RenderContent* prev_sibling = FindPrevSibling(old_child); if (nullptr == prev_sibling) return false; @@ -731,7 +731,7 @@ ON_RenderContent* ON_RenderContent::CImpl::FindChild(const wchar_t* child_slot_n { std::lock_guard lg(m_mutex); - auto* child_rc = m_first_child; + ON_RenderContent* child_rc = m_first_child; while (nullptr != child_rc) { if (child_rc->ChildSlotName() == child_slot_name) @@ -978,7 +978,7 @@ ON_XMLVariant ON_RenderContent::GetParameter(const wchar_t* name) const value.SetNull(); // Try to get the new V8 parameter section. - const auto* node = m_impl->m_node.GetNamedChild(ON_PARAMETERS_V8); + const ON_XMLNode* node = m_impl->m_node.GetNamedChild(ON_PARAMETERS_V8); if (nullptr != node) { // Got it, so use the new ON_XMLParametersV8 to get the parameter's value. @@ -1104,12 +1104,12 @@ const ON_RenderContent* ON_RenderContent::FindChild(const wchar_t* child_slot_na static ON_XMLNode* NewXMLNodeRecursive(const ON_RenderContent& rc) { - auto* node = new ON_XMLNode(rc.m_impl->m_node); + ON_XMLNode* node = new ON_XMLNode(rc.m_impl->m_node); - auto* child_rc = rc.m_impl->m_first_child; + ON_RenderContent* child_rc = rc.m_impl->m_first_child; while (nullptr != child_rc) { - auto* child_node = NewXMLNodeRecursive(*child_rc); + ON_XMLNode* child_node = NewXMLNodeRecursive(*child_rc); if (nullptr != child_node) { node->AttachChildNode(child_node); @@ -1123,14 +1123,14 @@ static ON_XMLNode* NewXMLNodeRecursive(const ON_RenderContent& rc) ON_wString ON_RenderContent::XML(bool recursive) const { - auto* node = &m_impl->m_node; + ON_XMLNode* node = &m_impl->m_node; if (recursive) { node = NewXMLNodeRecursive(*this); } - const auto logical_count = node->WriteToStream(nullptr, 0); + const ON__UINT32 logical_count = node->WriteToStream(nullptr, 0); auto* stream = new wchar_t[size_t(logical_count) + 1]; node->WriteToStream(stream, logical_count); stream[logical_count] = 0; @@ -1205,7 +1205,7 @@ ON_RenderContent::ChildIterator::~ChildIterator() ON_RenderContent* ON_RenderContent::ChildIterator::GetNextChild(void) { - auto* rc = m_impl->m_current; + ON_RenderContent* rc = m_impl->m_current; if (nullptr != rc) { m_impl->m_current = rc->m_impl->m_next_sibling; @@ -1235,7 +1235,7 @@ ON_RenderContent* NewRenderContentFromNode(const ON_XMLNode& node) { ON_RenderContent* rc = nullptr; - const auto& kind = node.TagName(); + const ON_wString& kind = node.TagName(); if (ON_KIND_MATERIAL == kind) rc = new ON_RenderMaterial; @@ -1294,7 +1294,7 @@ ON_Material ON_RenderMaterial::SimulatedMaterial(void) const ON_Material mat; - const auto* sim_node = m_impl->XMLNode_Simulation(); + const ON_XMLNode* sim_node = m_impl->XMLNode_Simulation(); if (nullptr != sim_node) { ON_XMLParameters p(*sim_node); @@ -1323,7 +1323,7 @@ ON_Material ON_RenderMaterial::SimulatedMaterial(void) const auto pbm = mat.PhysicallyBased(); auto brdf = ON_PhysicallyBasedMaterial::BRDFs::GGX; - const auto s = ParamHelper(p, ON_MAT_PBR_BRDF).AsString(); + const ON_wString s = ParamHelper(p, ON_MAT_PBR_BRDF).AsString(); if (s == ON_MAT_PBR_BRDF_WARD) brdf = ON_PhysicallyBasedMaterial::BRDFs::Ward; pbm->SetBRDF(brdf); @@ -1431,7 +1431,7 @@ ON_Environment ON_RenderEnvironment::SimulatedEnvironment(void) const ON_Environment env; - const auto* sim_node = m_impl->XMLNode_Simulation(); + const ON_XMLNode* sim_node = m_impl->XMLNode_Simulation(); if (nullptr != sim_node) { ON_XMLVariant v; @@ -1488,7 +1488,7 @@ ON_Texture ON_RenderTexture::SimulatedTexture(void) const ON_Texture tex; - const auto* sim_node = m_impl->XMLNode_Simulation(); + const ON_XMLNode* sim_node = m_impl->XMLNode_Simulation(); if (nullptr != sim_node) { ON_XMLVariant v; @@ -1551,10 +1551,10 @@ int ONX_Model::AddRenderMaterial(const wchar_t* mat_name) ON_RenderMaterial mat; mat.SetTypeId(uuidPB); - const auto unused_name = m_manifest.UnusedName(mat.ComponentType(), ON_nil_uuid, mat_name, nullptr, nullptr, 0, nullptr); + const ON_wString unused_name = m_manifest.UnusedName(mat.ComponentType(), ON_nil_uuid, mat_name, nullptr, nullptr, 0, nullptr); mat.SetName(unused_name); - const auto mcr = AddModelComponent(mat, true); + const ON_ModelComponentReference mcr = AddModelComponent(mat, true); const auto* model_mat = ON_RenderMaterial::Cast(mcr.ModelComponent()); if (nullptr == model_mat) { @@ -1572,10 +1572,10 @@ int ONX_Model::AddRenderEnvironment(const wchar_t* env_name) ON_RenderEnvironment env; env.SetTypeId(uuidBE); - const auto unused_name = m_manifest.UnusedName(env.ComponentType(), ON_nil_uuid, env_name, nullptr, nullptr, 0, nullptr); + const ON_wString unused_name = m_manifest.UnusedName(env.ComponentType(), ON_nil_uuid, env_name, nullptr, nullptr, 0, nullptr); env.SetName(unused_name); - const auto mcr = AddModelComponent(env, true); + const ON_ModelComponentReference mcr = AddModelComponent(env, true); const auto* model_env = ON_RenderEnvironment::Cast(mcr.ModelComponent()); if (nullptr == model_env) { @@ -1602,13 +1602,13 @@ int ONX_Model::AddRenderTexture(const wchar_t* fn) tex.SetTypeId(uuidBM); tex.SetParameter(ON_TEX_FILENAME, filename); - const auto tex_name = ON_FileSystemPath::FileNameFromPath(filename, false); + const ON_wString tex_name = ON_FileSystemPath::FileNameFromPath(filename, false); tex.SetName(tex_name); - const auto unused_name = m_manifest.UnusedName(tex.ComponentType(), ON_nil_uuid, tex_name, nullptr, nullptr, 0, nullptr); + const ON_wString unused_name = m_manifest.UnusedName(tex.ComponentType(), ON_nil_uuid, tex_name, nullptr, nullptr, 0, nullptr); tex.SetName(unused_name); - const auto mcr = AddModelComponent(tex, true); + const ON_ModelComponentReference mcr = AddModelComponent(tex, true); const auto* model_tex = ON_RenderTexture::Cast(mcr.ModelComponent()); if (nullptr == model_tex) { diff --git a/opennurbs_sha1.cpp b/opennurbs_sha1.cpp index c623ee87..3d0c836b 100644 --- a/opennurbs_sha1.cpp +++ b/opennurbs_sha1.cpp @@ -607,6 +607,13 @@ void ON_SHA1::AccumulateBool( AccumulateBytes(&c, sizeof(c)); } +void ON_SHA1::AccumulateInteger8( + char i +) +{ + AccumulateBytes(&i, 1); +} + void ON_SHA1::AccumulateInteger8( ON__INT8 i ) diff --git a/opennurbs_sha1.h b/opennurbs_sha1.h index bdb50569..20ae2f4e 100644 --- a/opennurbs_sha1.h +++ b/opennurbs_sha1.h @@ -439,6 +439,10 @@ public: const class ON_Xform& xform ); + void AccumulateInteger8( + char i + ); + void AccumulateInteger8( ON__INT8 i ); diff --git a/opennurbs_string_compare.cpp b/opennurbs_string_compare.cpp index ea19a818..19eb90f6 100644 --- a/opennurbs_string_compare.cpp +++ b/opennurbs_string_compare.cpp @@ -50,6 +50,8 @@ ON_StringMapOrdinalType ON_StringMapOrdinalTypeFromStringMapType( return ON_StringMapOrdinalType::UpperOrdinal; case ON_StringMapType::LowerCase: return ON_StringMapOrdinalType::LowerOrdinal; + case ON_StringMapType::Identity: + return ON_StringMapOrdinalType::Identity; } return ON_StringMapOrdinalType::Identity; } @@ -2961,4 +2963,4 @@ void ON_String::MakeLowerOrdinal() m_s, length ); -} \ No newline at end of file +} diff --git a/opennurbs_subd.cpp b/opennurbs_subd.cpp index 3fada286..79d02d4e 100644 --- a/opennurbs_subd.cpp +++ b/opennurbs_subd.cpp @@ -14195,7 +14195,7 @@ const ON_SubDVertex * ON_SubD::ReplaceFaceWithTriangleFan(ON_SubDFace * face, ON if (i < 4) face->m_edge4[i] = ON_SubDEdgePtr::Null; else - face->m_edgex[i - 4] = ON_SubDEdgePtr::Null;; + face->m_edgex[i - 4] = ON_SubDEdgePtr::Null; ON_SubDEdge* e = ON_SUBD_EDGE_POINTER(edges[i].m_ptr); e->RemoveFaceFromArray(face); const_cast(edges[i].RelativeVertex(0))->RemoveFaceFromArray(face); diff --git a/opennurbs_sun.cpp b/opennurbs_sun.cpp index 634bdca3..86595508 100644 --- a/opennurbs_sun.cpp +++ b/opennurbs_sun.cpp @@ -85,17 +85,17 @@ static double Planck(double lambda, double temp) static ON_4fColor ColorTemperature(double temperature) { // Use a variant of Planck's equation to get values for the three CIE wavelengths. - auto temp = monitor_white; + double temp = monitor_white; - auto er = Planck(0.60, temp); - auto eg = Planck(0.56, temp); - auto eb = Planck(0.44, temp); + double er = Planck(0.60, temp); + double eg = Planck(0.56, temp); + double eb = Planck(0.44, temp); - auto es = 1.0 / std::max(er, std::max(eg, eb)); + double es = 1.0 / std::max(er, std::max(eg, eb)); - const auto r_white = er * es; - const auto g_white = eg * es; - const auto b_white = eb * es; + const double r_white = er * es; + const double g_white = eg * es; + const double b_white = eb * es; temp = temperature; @@ -105,15 +105,15 @@ static ON_4fColor ColorTemperature(double temperature) es = 1.0 / std::max(er,std::max(eg, eb)); - const auto r = er * es / r_white; - const auto g = eg * es / g_white; - const auto b = eb * es / b_white; + const double r = er * es / r_white; + const double g = eg * es / g_white; + const double b = eb * es / b_white; es = 1.0 / std::max(r, std::max(g, b)); - const auto rr = float(pow(r * es, 0.15)); - const auto gr = float(pow(g * es, 0.15)); - const auto br = float(pow(b * es, 0.15)); + const float rr = float(pow(r * es, 0.15)); + const float gr = float(pow(g * es, 0.15)); + const float br = float(pow(b * es, 0.15)); return ON_4fColor(rr, gr, br, 1.0f); } @@ -319,7 +319,7 @@ int ON_Sun::DaylightSavingMinutes(void) const void ON_Sun::LocalDateTime(int& year, int& month, int& day, double& hours) const { - const auto* s = XMLPath_Sun(); + const wchar_t* s = XMLPath_Sun(); year = m_impl->GetParameter(s, ON_RDK_SUN_DATE_YEAR, 2000); month = m_impl->GetParameter(s, ON_RDK_SUN_DATE_MONTH, 1); day = m_impl->GetParameter(s, ON_RDK_SUN_DATE_DAY, 1); @@ -417,7 +417,7 @@ bool ON_Sun::SetLocalDateTime(int year, int month, int day, double hours) if ((year < MinYear()) || (year > MaxYear())) return false; - const auto* s = XMLPath_Sun(); + const wchar_t* s = XMLPath_Sun(); m_impl->SetParameter(s, ON_RDK_SUN_DATE_YEAR, year); m_impl->SetParameter(s, ON_RDK_SUN_DATE_MONTH, month); m_impl->SetParameter(s, ON_RDK_SUN_DATE_DAY, day); @@ -516,10 +516,10 @@ ON_4fColor ON_Sun::SunColorFromAltitude(double altitude) // Static. if (altitude < -TwilightZone()) return colDark; - const auto value = (30.0 * pow(std::max(0.0, altitude), 1.5)) + 500.0; + const double value = (30.0 * pow(std::max(0.0, altitude), 1.5)) + 500.0; auto temperature = std::min(5300.0, value); - auto col = ColorTemperature(temperature); + ON_4fColor col = ColorTemperature(temperature); if (altitude < 0.0) { diff --git a/opennurbs_symmetry.cpp b/opennurbs_symmetry.cpp index 5afa1fd6..b67edfb6 100644 --- a/opennurbs_symmetry.cpp +++ b/opennurbs_symmetry.cpp @@ -2183,7 +2183,7 @@ const ON_SHA1_Hash ON_Symmetry::SymmetryHash() const ON_SHA1 sha1; sha1.AccumulateBytes(&m_type, sizeof(m_type)); sha1.AccumulateBytes(&m_coordinates, sizeof(m_coordinates)); - sha1.AccumulateInteger8(m_inversion_order); + sha1.AccumulateUnsigned8(m_inversion_order); sha1.AccumulateInteger32(m_cyclic_order); sha1.AccumulateId(m_id); sha1.AccumulateDoubleArray(16, &m_inversion_transform.m_xform[0][0]); diff --git a/opennurbs_system.h b/opennurbs_system.h index 9f3c6e6d..1532b185 100644 --- a/opennurbs_system.h +++ b/opennurbs_system.h @@ -153,99 +153,56 @@ #endif +#pragma ON_PRAGMA_WARNING_BEFORE_DIRTY_INCLUDE +#include +#pragma ON_PRAGMA_WARNING_AFTER_DIRTY_INCLUDE +typedef int8_t ON__INT8; +typedef uint8_t ON__UINT8; +typedef int16_t ON__INT16; +typedef uint16_t ON__UINT16; +typedef int32_t ON__INT32; +typedef uint32_t ON__UINT32; +typedef int64_t ON__INT64; +typedef uint64_t ON__UINT64; + +#define ON_MAX_SIZE_T SIZE_MAX #if defined(ON_64BIT_RUNTIME) + /* 64 bit (8 byte) pointers */ #define ON_SIZEOF_POINTER 8 -/* ON_MAX_SIZET = maximum value of a size_t type */ -#define ON_MAX_SIZE_T 0xFFFFFFFFFFFFFFFFULL +#define ON__UINT_PTR_MAX UINT64_MAX -#if defined(ON_COMPILER_MSC) - -typedef __int64 ON__INT_PTR; -typedef unsigned __int64 ON__UINT_PTR; -#elif defined(_GNU_SOURCE) || defined(ON_COMPILER_CLANG) -typedef long long ON__INT_PTR; -typedef unsigned long long ON__UINT_PTR; -#endif -#define ON__UINT_PTR_MAX 0xFFFFFFFFFFFFFFFFULL +typedef ON__INT64 ON__INT_PTR; +typedef ON__UINT64 ON__UINT_PTR; #elif defined(ON_32BIT_RUNTIME) + /* 32 bit (4 byte) pointers */ #define ON_SIZEOF_POINTER 4 -/* ON_MAX_SIZET = maximum value of a size_t type */ -#define ON_MAX_SIZE_T 0xFFFFFFFFULL +#define ON__UINT_PTR_MAX UINT32_MAX -typedef int ON__INT_PTR; -typedef unsigned int ON__UINT_PTR; -#define ON__UINT_PTR_MAX 0xFFFFFFFFULL - -#endif - -// 8 bit integer -typedef char ON__INT8; - -// 8 bit unsigned integer -typedef unsigned char ON__UINT8; - -// 16 bit integer -typedef short ON__INT16; - -// 16 bit unsigned integer -typedef unsigned short ON__UINT16; - -// 32 bit integer -typedef int ON__INT32; - -// 32 bit unsigned integer -typedef unsigned int ON__UINT32; - -#if defined(ON_COMPILER_MSC) -// 64 bit integer -typedef __int64 ON__INT64; -// 64 bit unsigned integer -typedef unsigned __int64 ON__UINT64; - -#elif defined(_GNU_SOURCE) || defined(ON_COMPILER_CLANG) -// 64 bit integer -typedef long long ON__INT64; -// 64 bit unsigned integer -typedef unsigned long long ON__UINT64; - -#else - -#error Verify that long long is a 64 bit integer with your compiler! - -// 64 bit integer -typedef long long ON__INT64; - -// 64 bit unsigned integer -typedef unsigned long long ON__UINT64; - -#endif - - -// ON_INT_PTR must be an integer type with sizeof(ON_INT_PTR) = sizeof(void*). -#if 8 == ON_SIZEOF_POINTER - -#if defined(ON_COMPILER_GNU) || defined(ON_COMPILER_CLANG) -typedef long long ON__INT_PTR; -typedef unsigned long long ON__UINT_PTR; -#else -typedef __int64 ON__INT_PTR; -typedef unsigned __int64 ON__UINT_PTR; -#endif - -#elif 4 == ON_SIZEOF_POINTER - -typedef int ON__INT_PTR; -typedef unsigned int ON__UINT_PTR; +typedef ON__INT32 ON__INT_PTR; +typedef ON__UINT32 ON__UINT_PTR; #else #error Update OpenNURBS to work with new pointer size. #endif +ON_STATIC_ASSERT(sizeof(ON__INT8) == 1); +ON_STATIC_ASSERT(sizeof(ON__UINT8) == 1); +ON_STATIC_ASSERT(sizeof(ON__INT16) == 2); +ON_STATIC_ASSERT(sizeof(ON__UINT16) == 2); +ON_STATIC_ASSERT(sizeof(ON__INT32) == 4); +ON_STATIC_ASSERT(sizeof(ON__UINT32) == 4); +ON_STATIC_ASSERT(sizeof(ON__INT64) == 8); +ON_STATIC_ASSERT(sizeof(ON__UINT64) == 8); + +ON_STATIC_ASSERT_MSG(sizeof(ON__INT_PTR) == sizeof(void*), "ON_INT_PTR must be an integer type with sizeof(ON_INT_PTR) = sizeof(void*)"); +ON_STATIC_ASSERT_MSG(sizeof(ON__UINT_PTR) == sizeof(void*), "ON_UINT_PTR must be an integer type with sizeof(ON_UINT_PTR) = sizeof(void*)"); +ON_STATIC_ASSERT_MSG(ON_SIZEOF_POINTER == sizeof(void*), "ON_SIZEOF_POINTER must be equal to sizeof(void*)"); + /* //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// diff --git a/opennurbs_system_compiler.h b/opennurbs_system_compiler.h index d7e16814..24737249 100644 --- a/opennurbs_system_compiler.h +++ b/opennurbs_system_compiler.h @@ -42,6 +42,20 @@ // */ +/* +// Compilers with a better static_assert declaration +// may change ON_STATIC_ASSERT accordingly. +*/ +#if __cpp_static_assert >= 201411L // C++17 +# define ON_STATIC_ASSERT(expr) static_assert((expr)) +# define ON_STATIC_ASSERT_MSG(expr, msg) static_assert((expr), msg) +#elif __cpp_static_assert >= 200410L // C++11 +# define ON_STATIC_ASSERT(expr) static_assert((expr), #expr) +# define ON_STATIC_ASSERT_MSG(expr, msg) static_assert((expr), msg) +#else +# define ON_STATIC_ASSERT(expr) typedef char on_static_assert_t[(expr) != 0] +# define ON_STATIC_ASSERT_MSG(expr, msg) typedef char on_static_assert_t[(expr) != 0] +#endif /* // Compilers that require special declaration of callback functions diff --git a/opennurbs_xml.cpp b/opennurbs_xml.cpp index 33f8c448..5a6921e4 100644 --- a/opennurbs_xml.cpp +++ b/opennurbs_xml.cpp @@ -865,7 +865,7 @@ public: ON__UINT8* m_raw_buffer = nullptr; bool m_bTypePending = false; bool m_bReserved[3] = { false }; - Types m_type = Types::String; + Types m_type = Types::Null; }; ON_XMLVariant::ON_XMLVariant() @@ -976,6 +976,12 @@ ON_XMLVariant::ON_XMLVariant(const ON_XMLVariant& src) *this = src; } +ON_XMLVariant::~ON_XMLVariant() +{ + m_impl->~CImpl(); + m_impl = nullptr; +} + ON_Buffer& ON_XMLVariant::GetBuffer(void) const { return m_impl->GetBuffer(); @@ -1025,10 +1031,71 @@ const ON_XMLVariant& ON_XMLVariant::operator = (const ON_XMLVariant& src) return *this; } -ON_XMLVariant::~ON_XMLVariant() +bool ON_XMLVariant::operator == (const ON_XMLVariant& v) const { - m_impl->~CImpl(); - m_impl = nullptr; + if (m_impl->m_type != v.m_impl->m_type) + return false; + + if (m_impl->m_units != m_impl->m_units) + return false; + + switch (m_impl->m_type) + { + case Types::Bool: + return m_impl->m_bVal == v.m_impl->m_bVal; + + case Types::Integer: + return m_impl->m_iVal == v.m_impl->m_iVal; + + case Types::Float: + return IsFloatEqual(m_impl->m_fVal, v.m_impl->m_fVal) ? true : false; + + case Types::Double: + return IsDoubleEqual(m_impl->m_dVal, v.m_impl->m_dVal) ? true : false; + + case Types::DoubleArray2: + return ((IsDoubleEqual(m_impl->m_aVal[0], v.m_impl->m_aVal[0])) && + (IsDoubleEqual(m_impl->m_aVal[1], v.m_impl->m_aVal[1]))) ? true : false; + + case Types::DoubleArray3: + return ((IsDoubleEqual(m_impl->m_aVal[0], v.m_impl->m_aVal[0])) && + (IsDoubleEqual(m_impl->m_aVal[1], v.m_impl->m_aVal[1])) && + (IsDoubleEqual(m_impl->m_aVal[2], v.m_impl->m_aVal[2]))) ? true : false; + + case Types::DoubleColor4: + case Types::DoubleArray4: + return ((IsDoubleEqual(m_impl->m_aVal[0], v.m_impl->m_aVal[0])) && + (IsDoubleEqual(m_impl->m_aVal[1], v.m_impl->m_aVal[1])) && + (IsDoubleEqual(m_impl->m_aVal[2], v.m_impl->m_aVal[2])) && + (IsDoubleEqual(m_impl->m_aVal[3], v.m_impl->m_aVal[3]))) ? true : false; + + case Types::String: + return m_impl->m_sVal.CompareNoCase(v.m_impl->m_sVal) == 0; + + case Types::Uuid: + return (m_impl->m_uuidVal == v.m_impl->m_uuidVal) ? true : false; + + case Types::Time: + return m_impl->m_timeVal == v.m_impl->m_timeVal; + + case Types::Matrix: + for (int i = 0; i < 16; i++) + { + if (m_impl->m_aVal[i] != v.m_impl->m_aVal[i]) + return false; + } + return true; + + default: + ON_ASSERT(false); + } + + return false; +} + +bool ON_XMLVariant::operator != (const ON_XMLVariant& v) const +{ + return !(operator == (v)); } bool ON_XMLVariant::NeedsXMLEncode(void) const @@ -4029,12 +4096,25 @@ ON_XMLNode::ChildIterator::ChildIterator(const ON_XMLNode* pParent) } } +ON_XMLNode::ChildIterator::ChildIterator(const ChildIterator& other) +{ + m_impl = new (m_Impl) CImpl; IMPL_CHECK; + operator = (other); +} + ON_XMLNode::ChildIterator::~ChildIterator() { m_impl->~CImpl(); m_impl = nullptr; } +const ON_XMLNode::ChildIterator& ON_XMLNode::ChildIterator::operator = (const ChildIterator& other) +{ + m_impl->m_pCurrent = other.m_impl->m_pCurrent; + + return *this; +} + ON_XMLNode* ON_XMLNode::ChildIterator::GetNextChild(void) { auto* pNode = m_impl->m_pCurrent; @@ -4130,12 +4210,29 @@ ON_XMLNode::PropertyIterator::PropertyIterator(const ON_XMLNode* pNode, bool bSo } } +ON_XMLNode::PropertyIterator::PropertyIterator(const PropertyIterator& other) +{ + m_impl = new (m_Impl) CImpl; IMPL_CHECK; + operator = (other); +} + ON_XMLNode::PropertyIterator::~PropertyIterator() { m_impl->~CImpl(); m_impl = nullptr; } +const ON_XMLNode::PropertyIterator& ON_XMLNode::PropertyIterator::operator = (const PropertyIterator& other) +{ + m_impl->m_pCurrent = other.m_impl->m_pCurrent; + m_impl->m_pNode = other.m_impl->m_pNode; + m_impl->m_iIndex = other.m_impl->m_iIndex; + m_impl->m_bSorted = other.m_impl->m_bSorted; + m_impl->m_paSortedProperties = other.m_impl->m_paSortedProperties; + + return *this; +} + ON_XMLProperty* ON_XMLNode::PropertyIterator::GetNextProperty(void) { if (m_impl->m_bSorted) diff --git a/opennurbs_xml.h b/opennurbs_xml.h index 977a69b5..e46baed9 100644 --- a/opennurbs_xml.h +++ b/opennurbs_xml.h @@ -99,6 +99,9 @@ public: const ON_XMLVariant& operator = (const ON_XMLVariant& src); + bool operator == (const ON_XMLVariant& v) const; + bool operator != (const ON_XMLVariant& v) const; + ON__UINT32 DataCRC(ON__UINT32 current_remainder) const; public: @@ -392,15 +395,26 @@ public: // Utilities. ON_XMLProperty& GetDefaultProperty(void) const; - // Gets at nodes deep into the tree using a slash delimited path - ie "child/grandchild/great-grandchild" - // There's no checking for multiple nodes with the same name at each level of the tree, so if you use this - // stuff, you have to make sure you have unique node names at each level. - // relative to the current node, use "/" as a separator. - - ON_XMLNode* GetNodeAtPath(const wchar_t* path) const; - ON_XMLNode* CreateNodeAtPath(const wchar_t* path); + // Returns the full path to this node. ON_wString GetPathFromRoot(void) const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////// + // Gets at nodes deep into the tree using a slash-delimited path, i.e., "child/grandchild/great-grandchild". + // There's no checking for multiple nodes with the same name at each level of the tree, so if you use these + // methods, you have to make sure you have unique node names at each level. + + // Gets a child node given the relative path from the current node. If the node does not exist, the method + // returns null. The returned pointer should not be deleted by the caller. The child node is owned by its + // immediate parent at that position in the node hierarchy. + ON_XMLNode* GetNodeAtPath(const wchar_t* path) const; + + // Gets a child node given the relative path from the current node. If the node does not exist, it is + // created. This method should therefore never return null. The returned pointer should not be deleted + // by the caller. The child node is owned by its immediate parent at that position in the node hierarchy. + ON_XMLNode* CreateNodeAtPath(const wchar_t* path); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////// + // Emergency virtual function for future expansion. virtual void* EVF(const wchar_t* func, void* data); @@ -409,8 +423,11 @@ public: // Iteration. { public: ChildIterator(const ON_XMLNode* parent); + ChildIterator(const ChildIterator& other); virtual ~ChildIterator(); + const ChildIterator& operator = (const ChildIterator& other); + virtual ON_XMLNode* GetNextChild(void); // Emergency virtual function for future expansion. @@ -426,10 +443,13 @@ public: // Iteration. { public: PropertyIterator(const ON_XMLNode* parent, bool sorted = false); + PropertyIterator(const PropertyIterator& other); ~PropertyIterator(); ON_XMLProperty* GetNextProperty(void); + const PropertyIterator& operator = (const PropertyIterator& other); + private: class CImpl; CImpl* m_impl; diff --git a/opennurbs_zlib.cpp b/opennurbs_zlib.cpp index dfcefd1b..c2c27ab5 100644 --- a/opennurbs_zlib.cpp +++ b/opennurbs_zlib.cpp @@ -99,12 +99,17 @@ bool ON_BinaryArchive::WriteCompressedBuffer( return false; if ( sizeof__inbuffer > 0 && 0 == inbuffer ) return false; - + if (sizeof__inbuffer > UINT32_MAX) + return false; // number of bytes of uncompressed data - +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") if (!WriteSize(sizeof__inbuffer)) return false; +#pragma ON_PRAGMA_WARNING_POP + if ( 0 == sizeof__inbuffer ) return true; @@ -150,7 +155,11 @@ bool ON_BinaryArchive::WriteCompressedBuffer( bool ON_BinaryArchive::ReadCompressedBufferSize( size_t* sizeof__outbuffer ) { +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") return ReadSize(sizeof__outbuffer); +#pragma ON_PRAGMA_WARNING_POP } bool ON_BinaryArchive::ReadCompressedBuffer( // read and uncompress @@ -740,12 +749,16 @@ bool ON_CompressedBuffer::Write( ON_BinaryArchive& binary_archive ) const for(;;) { +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") rc = binary_archive.WriteSize(m_sizeof_uncompressed); if (!rc) break; rc = binary_archive.WriteSize((m_buffer_compressed && m_sizeof_compressed>0) ? m_sizeof_compressed : 0); if (!rc) break; +#pragma ON_PRAGMA_WARNING_POP rc = binary_archive.WriteInt(m_crc_uncompressed); if (!rc) break; @@ -786,12 +799,16 @@ bool ON_CompressedBuffer::Read( ON_BinaryArchive& binary_archive ) rc = ( 1 == major_version ); if ( !rc ) break; +#pragma ON_PRAGMA_WARNING_PUSH +#pragma ON_PRAGMA_WARNING_DISABLE_MSC(4996) +#pragma ON_PRAGMA_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") rc = binary_archive.ReadSize(&m_sizeof_uncompressed); if (!rc) break; rc = binary_archive.ReadSize(&m_sizeof_compressed); if (!rc) break; +#pragma ON_PRAGMA_WARNING_PUSH rc = binary_archive.ReadInt(&m_crc_uncompressed); if (!rc) break; @@ -861,6 +878,9 @@ bool ON_CompressedBuffer::Compress( if ( 0 == sizeof__inbuffer ) return true; + if (sizeof__inbuffer > UINT32_MAX) + return false; + // number of bytes of uncompressed data m_sizeof_uncompressed = sizeof__inbuffer;