diff --git a/.gitignore b/.gitignore index c19499795..a68d87ecf 100644 --- a/.gitignore +++ b/.gitignore @@ -98,3 +98,5 @@ node_modules/ bin/ obj/ x64/ +Properties/ +*.3dm diff --git a/src/bindings/bnd_extensions.cpp b/src/bindings/bnd_extensions.cpp index 70d3f2781..26b37ad48 100644 --- a/src/bindings/bnd_extensions.cpp +++ b/src/bindings/bnd_extensions.cpp @@ -560,6 +560,13 @@ BND_UUID BND_ONXModel_ObjectTable::Add(const BND_GeometryBase* geometry, const B return ON_UUID_to_Binding(rc); } +BND_UUID BND_ONXModel_ObjectTable::AddObject(const class BND_FileObject* object) +{ + const ON_Geometry* g = object ? object->m_geometry->GeometryPointer() : nullptr; + ON_UUID rc = Internal_ONX_Model_AddModelGeometry(m_model.get(), g, object->m_attributes); + return ON_UUID_to_Binding(rc); +} + void BND_ONXModel_ObjectTable::Delete(BND_UUID id) { ON_UUID _id = Binding_to_ON_UUID(id); @@ -1490,6 +1497,7 @@ void initExtensionsBindings(pybind11::module& m) .def("AddBrep", &BND_ONXModel_ObjectTable::AddBrep, py::arg("brep"), py::arg("attributes")=nullptr) .def("AddHatch", &BND_ONXModel_ObjectTable::AddHatch, py::arg("hatch"), py::arg("attributes")=nullptr) .def("Add", &BND_ONXModel_ObjectTable::Add, py::arg("geometry"), py::arg("attributes")=nullptr) + .def("AddObject", &BND_ONXModel_ObjectTable::AddObject, py::arg("object")) .def("GetBoundingBox", &BND_ONXModel_ObjectTable::GetBoundingBox) .def("Delete", &BND_ONXModel_ObjectTable::Delete, py::arg("id")) .def("FindId", &BND_ONXModel_ObjectTable::FindId, py::arg("id")) @@ -1807,6 +1815,7 @@ void initExtensionsBindings(void*) .function("addMesh", &BND_ONXModel_ObjectTable::AddMesh, allow_raw_pointers()) .function("addBrep", &BND_ONXModel_ObjectTable::AddBrep, allow_raw_pointers()) .function("add", &BND_ONXModel_ObjectTable::Add, allow_raw_pointers()) + .function("addObject", &BND_ONXModel_ObjectTable::AddObject, allow_raw_pointers()) .function("getBoundingBox", &BND_ONXModel_ObjectTable::GetBoundingBox) .function("deleteItem", &BND_ONXModel_ObjectTable::Delete) .function("findId", &BND_ONXModel_ObjectTable::FindId, allow_raw_pointers()) diff --git a/src/bindings/bnd_extensions.h b/src/bindings/bnd_extensions.h index 04905c287..92cfbc3a7 100644 --- a/src/bindings/bnd_extensions.h +++ b/src/bindings/bnd_extensions.h @@ -77,6 +77,7 @@ class BND_ONXModel_ObjectTable //Guid AddLeader4(string text, Plane plane, IEnumerable points) BND_UUID AddHatch(const class BND_Hatch* hatch, const class BND_3dmObjectAttributes* attributes); BND_UUID Add(const class BND_GeometryBase* geometry, const class BND_3dmObjectAttributes* attributes); + BND_UUID AddObject(const class BND_FileObject* object); void Delete(BND_UUID objectId); //int Delete(IEnumerable objectIds) diff --git a/src/dotnet/Properties/AssemblyInfo.cs b/src/dotnet/Properties/AssemblyInfo.cs index 1dc96fe65..a5fcdc749 100644 --- a/src/dotnet/Properties/AssemblyInfo.cs +++ b/src/dotnet/Properties/AssemblyInfo.cs @@ -145,3 +145,9 @@ "341a3109b0528c9775fe5b46bfc85ecb90e75f265bef0700eb98176671b4ff9c7e74ac683ebe8d" + "50cd4a1c4538d6bf94a7c7c48da9fee90327e273fbc0208c76f6782220d290dee6067981d33ea4" + "a3b345cf")] + +[assembly: InternalsVisibleTo("Export_DAE, PublicKey=002400000480000094000000060200000024000052534131000400000100010083c66ae8bfbbea" + + "010a18559b1502c1b79e1fbb74b62ea03fec9bd46ec6fec5c1917c8a92c44f96a449f87cce288e" + + "341a3109b0528c9775fe5b46bfc85ecb90e75f265bef0700eb98176671b4ff9c7e74ac683ebe8d" + + "50cd4a1c4538d6bf94a7c7c48da9fee90327e273fbc0208c76f6782220d290dee6067981d33ea4" + + "a3b345cf")] diff --git a/src/dotnet/hostutils.cs b/src/dotnet/hostutils.cs index 1c531a4bd..0598807fa 100644 --- a/src/dotnet/hostutils.cs +++ b/src/dotnet/hostutils.cs @@ -2629,7 +2629,8 @@ public static void DebugString(string msg) #if RHINO_SDK if (m_bSendDebugToRhino) RhinoApp.WriteLine(msg); - UnsafeNativeMethods.RHC_DebugPrint(msg); + else + UnsafeNativeMethods.RHC_DebugPrint(msg); #else Console.Write(msg); #endif @@ -3761,7 +3762,7 @@ public static void InitializeRhinoCommon() RegisterNamedCallback("FireLicenseStateChangedEvent", RhinoApp.FireLicenseStateChangedEvent); RegisterNamedCallback("RhinoView.ShowToast", Rhino.Display.RhinoView.FireShowToast); - DebugString("Initializing RhinoCommon"); + //DebugString("Initializing RhinoCommon"); UnsafeNativeMethods.RHC_SetGetNowProc(m_getnow_callback, m_getformattedtime_callback); UnsafeNativeMethods.RHC_SetPythonEvaluateCallback(m_evaluate_callback); UnsafeNativeMethods.RHC_SetTextFieldEvalCallback(m_eval_textfield_callback); diff --git a/src/dotnet/opennurbs/opennurbs_beam.cs b/src/dotnet/opennurbs/opennurbs_beam.cs index 8cf59c8d8..595268aef 100644 --- a/src/dotnet/opennurbs/opennurbs_beam.cs +++ b/src/dotnet/opennurbs/opennurbs_beam.cs @@ -606,16 +606,15 @@ public Mesh GetMesh(MeshType meshType) /// /// The mesh. /// The mesh type. - /// A bool. - [ConstOperation] + /// True on success. public bool SetMesh(Mesh mesh, MeshType meshType) { if (null == mesh ) return false; - IntPtr ptr_const_this = ConstPointer(); + IntPtr ptr_this = NonConstPointer(); IntPtr ptr_const_mesh = mesh.ConstPointer(); - bool result = UnsafeNativeMethods.ON_Extrusion_SetMesh( ptr_const_this, ptr_const_mesh, (int)meshType ); + bool result = UnsafeNativeMethods.ON_Extrusion_SetMesh( ptr_this, ptr_const_mesh, (int)meshType ); GC.KeepAlive(mesh); return result; } diff --git a/src/dotnet/opennurbs/opennurbs_extensions.cs b/src/dotnet/opennurbs/opennurbs_extensions.cs index 7c8c39bf4..ef5b8086e 100644 --- a/src/dotnet/opennurbs/opennurbs_extensions.cs +++ b/src/dotnet/opennurbs/opennurbs_extensions.cs @@ -513,7 +513,7 @@ public bool Write(string path, File3dmWriteOptions options) options = options ?? new File3dmWriteOptions(); IntPtr ptr_this = NonConstPointer(); - return UnsafeNativeMethods.ONX_Model_WriteFile(ptr_this, path, options.Version, + return UnsafeNativeMethods.ONX_Model_WriteFile(ptr_this, path, options.File3dmValidVersion, (uint)options.RenderMeshFlags, (uint)options.AnalysisMeshFlags, options.SaveUserData, IntPtr.Zero); @@ -1423,6 +1423,16 @@ public File3dmWriteOptions() /// 5.9 public int Version { get; set; } + internal int File3dmValidVersion + { + get + { + int version = Version; + if (version >= 5 && version < 50) + version *= 10; + return version; + } + } /// /// Include Render meshes in the file. Default is true /// @@ -1692,6 +1702,7 @@ public abstract class CommonComponentTable : where T : ModelComponent { internal ManifestTable m_manifest; + internal bool _nonIndexedTable = false; internal CommonComponentTable(ManifestTable manifest) { @@ -1770,6 +1781,34 @@ public virtual T FindId(Guid id) /// internal T __FindIndexInternal(int index) { + if (_nonIndexedTable) + { + // Bill Cook 2023-12-15 + // RH-75882 and RH-75883 + // This class probably shouldn't have been an IList, but it is. The current .Net implementations of First() and + // Last() check for Ilist and if it's there they use an indexed accessor. Some things, like the ObjectTable, + // are non-indexed tables on the C++ side, so First() and Last() weren't working. + // + // NOTE: This is still a non-standard implementation of the indexer function Item[index], as it returns null when + // the index is out of range instead of throwing an exception. Doing otherwise here could break a lot of stuff. + // You could override Item[index] for a specific object if this functionality is desired. (Also RemoveAt, Insert, + // etc. - there are probably a bunch of them). Again, for now this was deemed dangerous/overkill to fix the issue. + // + // REMEMBER: you cannot call the First and Last functions here because they check to see if this class + // implements IList, which it does, and will recurse back into this function. The only choice is to start + // at the beginning and trudge through it. It should be possible to optimize this more on the C++ side, because + // in C++ it is a doubly-linked list. For now it this is being done unidirectionally because it was a very + // narrow edge case. + using (IEnumerator e = GetEnumerator()) + { + int i = index; + while (i-- >= 0) + { + if (!e.MoveNext()) return null; + } + return (T)e.Current; + } + } return (T)m_manifest.FindIndex(index, ComponentType); } @@ -4132,6 +4171,7 @@ public File3dmObject[] GroupMembers(int groupIndex) /// Adds a new empty group to the group table. /// /// >=0 index of new group or -1 on error. + /// 8.4 public int AddGroup() { IntPtr ptrFile3dm = m_parent.NonConstPointer(); diff --git a/src/dotnet/opennurbs/opennurbs_nurbssurface.cs b/src/dotnet/opennurbs/opennurbs_nurbssurface.cs index 284e09ed8..2f7643799 100644 --- a/src/dotnet/opennurbs/opennurbs_nurbssurface.cs +++ b/src/dotnet/opennurbs/opennurbs_nurbssurface.cs @@ -1857,7 +1857,6 @@ public double SuperfluousKnot(bool start) return UnsafeNativeMethods.ON_NurbsSurface_SuperfluousKnot(const_ptr_surface, m_direction, start ? 0 : 1); } -#if RHINO_SDK /// /// Gets the style of the knot vector. /// @@ -1870,7 +1869,6 @@ public KnotStyle KnotStyle return (KnotStyle)UnsafeNativeMethods.ON_NurbsSurface_KnotStyle(const_ptr_surface, m_direction); } } -#endif //RHINO_SDK /// /// Gets or sets the knot vector value at the given index. diff --git a/src/dotnet/opennurbs/opennurbs_object.cs b/src/dotnet/opennurbs/opennurbs_object.cs index 5365271ec..1d9d4ad76 100644 --- a/src/dotnet/opennurbs/opennurbs_object.cs +++ b/src/dotnet/opennurbs/opennurbs_object.cs @@ -180,10 +180,10 @@ internal virtual IntPtr NonConstPointer() { if (IntPtr.Zero != m_ptr) { - // m_ptr points ot an ON_Object. + // m_ptr points at an ON_Object. // Repair corruption that causes crashes in breps and meshes. // The parameters 0,0 mean: - // The first 0 parameter = bReplair and means detect but do not repair - so exception handler can see the damaged original information. + // The first 0 parameter = bRepair and means detect but do not repair - so exception handler can see the damaged original information. // The second 0 parameter = bSilentError means call C++ ON_ERROR() so a dev running a debug build gets a chance to see // the corrupt brep/mesh immediately. if (PerformCorruptionTesting && 0 != UnsafeNativeMethods.ON_Object_IsCorrupt(m_ptr, 0, 0)) diff --git a/src/dotnet/opennurbs/opennurbs_planesurface.cs b/src/dotnet/opennurbs/opennurbs_planesurface.cs index 09065e1db..52ef07b59 100644 --- a/src/dotnet/opennurbs/opennurbs_planesurface.cs +++ b/src/dotnet/opennurbs/opennurbs_planesurface.cs @@ -92,7 +92,6 @@ public Plane Plane } } -#if RHINO_SDK /// /// Gets the extents of the plane surface. /// @@ -129,7 +128,6 @@ public void SetExtents(int direction, Interval extents, bool syncDomain) UnsafeNativeMethods.ON_PlaneSurface_SetExtents(ptr_this, direction, extents, syncDomain); } -#endif //RhHINO_SDK /// /// Computes a polygon mesh of the surface made of one quad. diff --git a/src/dotnet/opennurbs/opennurbs_subd.cs b/src/dotnet/opennurbs/opennurbs_subd.cs index 393c84722..59c986cb2 100644 --- a/src/dotnet/opennurbs/opennurbs_subd.cs +++ b/src/dotnet/opennurbs/opennurbs_subd.cs @@ -435,6 +435,127 @@ public static SubD CreateFromSurface(Surface surface, SubDFromSurfaceMethods met return null; } +#if RHINO_SDK + + /// + /// Creates a SubD sphere made from quad faces. + /// + /// Location, size and orientation of the sphere. + /// + /// If vertexLocation = SubDComponentLocation::ControlNet, + /// then the control net points will be on the surface of the sphere. + /// Otherwise the limit surface points will be on the sphere. + /// + /// + /// The resulting sphere will have 6*4^subdivision level quads. + /// (0 for 6 quads, 1 for 24 quads, 2 for 96 quads, ...). + /// + /// + /// If the input parameters are valid, a SubD quad sphere is returned. Otherwise null is returned. + /// + /// 8.4 + [CLSCompliant(false)] + public static SubD CreateQuadSphere(Sphere sphere, SubDComponentLocation vertexLocation, uint quadSubdivisionLevel) + { + IntPtr ptr_subd = UnsafeNativeMethods.ON_SubD_CreateSubDQuadSphere(ref sphere, vertexLocation, quadSubdivisionLevel); + if (IntPtr.Zero != ptr_subd) + return new SubD(ptr_subd, null); + return null; + } + + /// + /// Creates a SubD sphere made from polar triangle fans and bands of quads. + /// The result resembles a globe with triangle fans at the poles and the + /// edges forming latitude parallels and longitude meridians. + /// + /// Location, size and orientation of the sphere. + /// + /// If vertexLocation = SubDComponentLocation::ControlNet, + /// then the control net points will be on the surface of the sphere. + /// Otherwise the limit surface points will be on the sphere. + /// + /// + /// Number of faces along the sphere's meridians. (axialFaceCount >= 2) + /// For example, if you wanted each face to span 30 degrees of latitude, + /// you would pass 6 (=180 degrees/30 degrees) for axialFaceCount. + /// + /// + /// Number of faces around the sphere's parallels. (equatorialFaceCount >= 3) + /// For example, if you wanted each face to span 30 degrees of longitude, + /// you would pass 12 (=360 degrees/30 degrees) for equatorialFaceCount. + /// + /// + /// If the input parameters are valid, a SubD globe sphere is returned. Otherwise null is returned. + /// + /// 8.4 + [CLSCompliant(false)] + public static SubD CreateGlobeSphere(Sphere sphere, SubDComponentLocation vertexLocation, uint axialFaceCount, uint equatorialFaceCount) + { + IntPtr ptr_subd = UnsafeNativeMethods.ON_SubD_CreateSubDGlobeSphere(ref sphere, vertexLocation, axialFaceCount, equatorialFaceCount); + if (IntPtr.Zero != ptr_subd) + return new SubD(ptr_subd, null); + return null; + } + + /// + /// Creates a SubD sphere made from triangular faces. + /// This is a goofy topology for a Catmull-Clark subdivision surface + /// (all triangles and all vertices have 5 or 6 edges). + /// You may want to consider using the much behaved result from + /// CreateSubDQuadSphere() or even the result from CreateSubDGlobeSphere(). + /// + /// Location, size and orientation of the sphere. + /// + /// If vertexLocation = SubDComponentLocation::ControlNet, + /// then the control net points will be on the surface of the sphere. + /// Otherwise the limit surface points will be on the sphere. + /// + /// + /// The resulting sphere will have 20*4^subdivision level triangles. + /// (0 for 20 triangles, 1 for 80 triangles, 2 for 320 triangles, ...). + /// + /// + /// If the input parameters are valid, a SubD tri sphere is returned. Otherwise null is returned. + /// + /// 8.4 + [CLSCompliant(false)] + public static SubD CreateTriSphere(Sphere sphere, SubDComponentLocation vertexLocation, uint triSubdivisionLevel) + { + IntPtr ptr_subd = UnsafeNativeMethods.ON_SubD_CreateSubDTriSphere(ref sphere, vertexLocation, triSubdivisionLevel); + if (IntPtr.Zero != ptr_subd) + return new SubD(ptr_subd, null); + return null; + } + + /// + /// Creates a SubD sphere based on an icosohedron (20 triangular faces and 5 valent vertices). + /// This is a goofy topology for a Catmull-Clark subdivision surface + /// (all triangles, all vertices have 5 edges). + /// You may want to consider using the much behaved result from + /// CreateSubDQuadSphere(sphere, vertexLocation, 1) + /// or even the result from CreateSubDGlobeSphere(). + /// + /// Location, size and orientation of the sphere. + /// + /// If vertexLocation = SubDComponentLocation::ControlNet, + /// then the control net points will be on the surface of the sphere. + /// Otherwise the limit surface points will be on the sphere. + /// + /// + /// If the input parameters are valid, a SubD icosahedron is returned. Otherwise null is returned. + /// + /// 8.4 + [CLSCompliant(false)] + public static SubD CreateIcosahedron(Sphere sphere, SubDComponentLocation vertexLocation) + { + IntPtr ptr_subd = UnsafeNativeMethods.ON_SubD_CreateSubDIcosahedron(ref sphere, vertexLocation); + if (IntPtr.Zero != ptr_subd) + return new SubD(ptr_subd, null); + return null; + } + +#endif + /// /// Resets the SubD to the default face packing if adding creases or deleting faces breaks the quad grids. /// It does not change the topology or geometry of the SubD. SubD face packs always stop at creases. diff --git a/src/dotnet/rhino/rhinosdkdisplaypipelineattributes.cs b/src/dotnet/rhino/rhinosdkdisplaypipelineattributes.cs index 690572de1..1075cfed8 100644 --- a/src/dotnet/rhino/rhinosdkdisplaypipelineattributes.cs +++ b/src/dotnet/rhino/rhinosdkdisplaypipelineattributes.cs @@ -966,6 +966,30 @@ public bool ShowPointClouds get { return GetBool(UnsafeNativeMethods.DisplayPipelineAttributesBool.ShowPointClouds); } set { SetBool(UnsafeNativeMethods.DisplayPipelineAttributesBool.ShowPointClouds, value); } } + + /// 8.4 + public PointStyle PointCloudStyle + { + get + { + IntPtr const_ptr_this = ConstPointer(); + PointStyle rc = PointStyle.Simple; + UnsafeNativeMethods.CDisplayPipelineAttributes_GetSetPointCloudStyle(const_ptr_this, true, ref rc); + return rc; + } + set + { + IntPtr ptr_this = NonConstPointer(); + UnsafeNativeMethods.CDisplayPipelineAttributes_GetSetPointCloudStyle(ptr_this, false, ref value); + } + } + + /// 8.4 + public float PointCloudRadius + { + get { return GetInt(UnsafeNativeMethods.DisplayAttributesInt.PointCloudSize); } + set { SetInt(UnsafeNativeMethods.DisplayAttributesInt.PointCloudSize, (int)value); } + } #endregion diff --git a/src/dotnet/rhino/rhinosdkdoc.cs b/src/dotnet/rhino/rhinosdkdoc.cs index dd22a6378..da2b52132 100644 --- a/src/dotnet/rhino/rhinosdkdoc.cs +++ b/src/dotnet/rhino/rhinosdkdoc.cs @@ -5634,7 +5634,7 @@ public sealed class ObjectTable : RhinoDocCommonTable, ICollection { - internal ObjectTable(RhinoDoc doc) : base(doc){} + internal ObjectTable(RhinoDoc doc) : base(doc){ _nonIndexedTable = true; } /// /// Gets the document that owns this object table. diff --git a/src/dotnet/rhino/rhinosdkobject.cs b/src/dotnet/rhino/rhinosdkobject.cs index b5bf3ff97..b55d5e16d 100644 --- a/src/dotnet/rhino/rhinosdkobject.cs +++ b/src/dotnet/rhino/rhinosdkobject.cs @@ -620,7 +620,39 @@ public static Commands.Result MeshObjects(System.Collections.Generic.IEnumerable var ptr_mesh_parameters = parameters.NonConstPointer(); var ptr_mesharray = mesh_array.NonConstPointer(); var ptr_attributesarray = UnsafeNativeMethods.ON_SimpleArray_3dmObjectAttributes_New(); - var rc = UnsafeNativeMethods.RHC_RhinoMeshObjects(ptr_rhinoobject_array, ref ui_style, ptr_mesh_parameters, ptr_mesharray, ptr_attributesarray); + var rc = UnsafeNativeMethods.RHC_RhinoMeshObjects(ptr_rhinoobject_array, ref ui_style, ptr_mesh_parameters, ptr_mesharray, ptr_attributesarray, true); + meshes = mesh_array.ToNonConstArray(); + var attrib_count = UnsafeNativeMethods.ON_SimpleArray_3dmObjectAttributes_Count(ptr_attributesarray); + attributes = new ObjectAttributes[attrib_count]; + for (var i = 0; i < attrib_count; i++) + { + var ptr_attribute = UnsafeNativeMethods.ON_SimpleArray_3dmObjectAttributes_Get(ptr_attributesarray, i); + attributes[i] = new ObjectAttributes(ptr_attribute); + } + UnsafeNativeMethods.ON_SimpleArray_3dmObjectAttributes_Delete(ptr_attributesarray); + return (Commands.Result)rc; + } + } + + /// Meshes Rhino objects. + /// The Rhino objects to mesh. + /// The parameters used to create the meshes. + /// The created meshes are appended to this array. + /// The object attributes that coincide with each created mesh are appended to this array. + /// Set true to compute meshes in a worker thread. + /// The results of the calculation. + /// 8.4 + public static Commands.Result MeshObjects(System.Collections.Generic.IEnumerable rhinoObjects, MeshingParameters parameters, out Mesh[] meshes, out ObjectAttributes[] attributes, bool useWorkerThread) + { + using (var rhinoobject_array = new Runtime.InternalRhinoObjectArray(rhinoObjects)) + using (var mesh_array = new SimpleArrayMeshPointer()) + { + var ptr_rhinoobject_array = rhinoobject_array.NonConstPointer(); + var ui_style = -1; //no user interface + var ptr_mesh_parameters = parameters.NonConstPointer(); + var ptr_mesharray = mesh_array.NonConstPointer(); + var ptr_attributesarray = UnsafeNativeMethods.ON_SimpleArray_3dmObjectAttributes_New(); + var rc = UnsafeNativeMethods.RHC_RhinoMeshObjects(ptr_rhinoobject_array, ref ui_style, ptr_mesh_parameters, ptr_mesharray, ptr_attributesarray, useWorkerThread); meshes = mesh_array.ToNonConstArray(); var attrib_count = UnsafeNativeMethods.ON_SimpleArray_3dmObjectAttributes_Count(ptr_attributesarray); attributes = new ObjectAttributes[attrib_count]; @@ -652,7 +684,7 @@ public static Commands.Result MeshObjects(System.Collections.Generic.IEnumerable var ptr_mesh_parameters = parameters.NonConstPointer(); var ptr_mesharray = mesh_array.NonConstPointer(); var ptr_attributesarray = UnsafeNativeMethods.ON_SimpleArray_3dmObjectAttributes_New(); - var rc = UnsafeNativeMethods.RHC_RhinoMeshObjects(ptr_rhinoobject_array, ref ui_style, ptr_mesh_parameters, ptr_mesharray, ptr_attributesarray); + var rc = UnsafeNativeMethods.RHC_RhinoMeshObjects(ptr_rhinoobject_array, ref ui_style, ptr_mesh_parameters, ptr_mesharray, ptr_attributesarray, true); simpleDialog = ui_style == 0; meshes = mesh_array.ToNonConstArray(); var attrib_count = UnsafeNativeMethods.ON_SimpleArray_3dmObjectAttributes_Count(ptr_attributesarray); diff --git a/src/dotnet/rhino/rhinosdkobjectattributes.cs b/src/dotnet/rhino/rhinosdkobjectattributes.cs index db09b9e69..36d0c13a7 100644 --- a/src/dotnet/rhino/rhinosdkobjectattributes.cs +++ b/src/dotnet/rhino/rhinosdkobjectattributes.cs @@ -65,9 +65,9 @@ internal ObjectAttributes(IntPtr pNonConstAttributes) ConstructNonConstObject(pNonConstAttributes); } -#if RHINO_SDK internal override IntPtr NonConstPointer() { +#if RHINO_SDK var rhinoObjectParent = m__parent as RhinoObject; if (rhinoObjectParent != null && rhinoObjectParent.m_pRhinoObject != IntPtr.Zero) { @@ -75,6 +75,7 @@ internal override IntPtr NonConstPointer() if (ptr_this != IntPtr.Zero) return ptr_this; } +#endif var file3dmParent = m__parent as FileIO.File3dmObject; if (file3dmParent!=null) { @@ -82,6 +83,7 @@ internal override IntPtr NonConstPointer() } return base.NonConstPointer(); } +#if RHINO_SDK internal ObjectAttributes(RhinoObject parentObject) { diff --git a/src/dotnet/rhino/rhinosdkobjectmanager.cs b/src/dotnet/rhino/rhinosdkobjectmanager.cs index ce582afa0..704b21281 100644 --- a/src/dotnet/rhino/rhinosdkobjectmanager.cs +++ b/src/dotnet/rhino/rhinosdkobjectmanager.cs @@ -25,6 +25,7 @@ public class NodeIds public static Guid BlockInstances => UnsafeNativeMethods.RhinoObjectManager_GetNodeId(UnsafeNativeMethods.ObjectManager_NodeIds.NodeBlockInstances); public static Guid BlockInstance => UnsafeNativeMethods.RhinoObjectManager_GetNodeId(UnsafeNativeMethods.ObjectManager_NodeIds.NodeBlockInstance); public static Guid Geometry => UnsafeNativeMethods.RhinoObjectManager_GetNodeId(UnsafeNativeMethods.ObjectManager_NodeIds.NodeGeometry); + public static Guid SimilarBlockInstances => UnsafeNativeMethods.RhinoObjectManager_GetNodeId(UnsafeNativeMethods.ObjectManager_NodeIds.NodeSimilarBlockInstances); } internal static void CleanUp() diff --git a/src/dotnet/rhino/rhinosdkplugin.cs b/src/dotnet/rhino/rhinosdkplugin.cs index 72ae344c3..a564348cf 100644 --- a/src/dotnet/rhino/rhinosdkplugin.cs +++ b/src/dotnet/rhino/rhinosdkplugin.cs @@ -155,15 +155,15 @@ internal static PlugIn Create(Type pluginType, string pluginName, string pluginV { if (pluginAssembly == null) pluginAssembly = pluginType.Assembly; - HostUtils.DebugString("[PlugIn::Create] Start"); - if (!string.IsNullOrEmpty(pluginName)) - HostUtils.DebugString(" plugin_name = " + pluginName); + // HostUtils.DebugString("[PlugIn::Create] Start"); + // if (!string.IsNullOrEmpty(pluginName)) + // HostUtils.DebugString(" plugin_name = " + pluginName); PlugIn rc; Guid plugin_id = Guid.Empty; m_bOkToConstruct = true; try { - HostUtils.DebugString(" Looking for plug-in's GuidAttribute"); + //HostUtils.DebugString(" Looking for plug-in's GuidAttribute"); object[] idAttr = pluginAssembly.GetCustomAttributes(typeof(GuidAttribute), false); if (idAttr.Length > 0) { @@ -173,7 +173,7 @@ internal static PlugIn Create(Type pluginType, string pluginName, string pluginV if (string.IsNullOrEmpty(pluginName)) { - HostUtils.DebugString(" Looking for plug-in's AssemblyTitleAttribute"); + //HostUtils.DebugString(" Looking for plug-in's AssemblyTitleAttribute"); object[] titleAttr = pluginAssembly.GetCustomAttributes(typeof(System.Reflection.AssemblyTitleAttribute), false); System.Reflection.AssemblyTitleAttribute title = (System.Reflection.AssemblyTitleAttribute)(titleAttr[0]); pluginName = title.Title; @@ -196,7 +196,7 @@ internal static PlugIn Create(Type pluginType, string pluginName, string pluginV m_bOkToConstruct = false; if (rc != null) { - HostUtils.DebugString(" Created PlugIn Instance"); + //HostUtils.DebugString(" Created PlugIn Instance"); if (string.IsNullOrEmpty(pluginVersion)) { pluginVersion = pluginAssembly.GetName().Version.ToString(); @@ -269,7 +269,7 @@ internal static PlugIn Create(Type pluginType, string pluginName, string pluginV } } } - HostUtils.DebugString("[PlugIn::Create] Finished"); + //HostUtils.DebugString("[PlugIn::Create] Finished"); return rc; } @@ -2324,13 +2324,13 @@ internal static UnsafeNativeMethods.LoadPlugInFileReturnCodesConsts LoadPlugInHe bool version_check_passed = false; if( index_rhinocommon>=0 ) version_check_passed = CheckPlugInVersioning( referenced_assemblies[index_rhinocommon] ); - if( !version_check_passed && !CheckPlugInCompatibility(path, displayDebugInfo) ) + if( !version_check_passed && !CheckPlugInCompatibility(path) ) { return UnsafeNativeMethods.LoadPlugInFileReturnCodesConsts.Incompatible; } - if(displayDebugInfo) - RhinoApp.Write("- plug-in passes RhinoCommon.DLL reference version check\n"); + // if(displayDebugInfo) + // RhinoApp.Write("- plug-in passes RhinoCommon.DLL reference version check\n"); // 15 August. 2008 S. Baer // Test to make sure plug-in developers didn't accidentally copy RhinoCommon.DLL @@ -2364,8 +2364,8 @@ internal static UnsafeNativeMethods.LoadPlugInFileReturnCodesConsts LoadPlugInHe // At this point, we have determined that this is a RhinoCommon plug-in // We've done all the checking that we can do without actually loading // the DLL ( and resolving links) - if(displayDebugInfo) - RhinoApp.Write("- loading assembly using Reflection::Assembly::LoadFrom\n"); + // if(displayDebugInfo) + // RhinoApp.Write("- loading assembly using Reflection::Assembly::LoadFrom\n"); if(ironpython_referenced) { @@ -2385,8 +2385,8 @@ internal static UnsafeNativeMethods.LoadPlugInFileReturnCodesConsts LoadPlugInHe var plugin_assembly = HostUtils.LoadAssemblyFrom(path); - if(displayDebugInfo) - RhinoApp.Write("- extracting plug-in attributes to determine vendor information\n"); + // if(displayDebugInfo) + // RhinoApp.Write("- extracting plug-in attributes to determine vendor information\n"); // Fill out all of the info strings using Assembly attributes in the plugin ExtractPlugInAttributes( plugin_assembly, pluginInfo ); if (UnsafeNativeMethods.CRhinoPlugInInfo_SilentBlock(pluginInfo)) @@ -2394,14 +2394,14 @@ internal static UnsafeNativeMethods.LoadPlugInFileReturnCodesConsts LoadPlugInHe // All of the major tests have passed // Find and create the plug-in and command classes through reflection - if(displayDebugInfo) - RhinoApp.Write("- creating plug-in and command classes\n"); + // if(displayDebugInfo) + // RhinoApp.Write("- creating plug-in and command classes\n"); if( !CreateFromAssembly( plugin_assembly, displayDebugInfo, index_rhinocommon==-1) ) return UnsafeNativeMethods.LoadPlugInFileReturnCodesConsts.LoadError; - if(displayDebugInfo) - RhinoApp.Write("RhinoCommon successfully loaded {0}\n\n", path); + // if(displayDebugInfo) + // RhinoApp.Write("RhinoCommon successfully loaded {0}\n\n", path); } catch (Exception ex) { @@ -2502,7 +2502,7 @@ static string ComputeMd5Hash(string path) return hash; } } - static bool CheckPlugInCompatibility(string path, bool displayDebugInfo) + static bool CheckPlugInCompatibility(string path) { // 10 June 2016 (S. Baer) // We will probably want to completely redo this caching scheme about @@ -2549,7 +2549,7 @@ static bool CheckPlugInCompatibility(string path, bool displayDebugInfo) // a given file. This way I'm not worrying about plug-in names or // versions which is in the spirit of using Compat in the first place! string hash = ComputeMd5Hash(path); - if (displayDebugInfo) RhinoApp.WriteLine("- MD5: {0}", hash); + // if (displayDebugInfo) RhinoApp.WriteLine("- MD5: {0}", hash); // check cache using md5 in case we've already checked this file // NOTE: cache should be destroyed when Rhino is updated @@ -2646,10 +2646,10 @@ void DoCheck(string filePath) } } - RhinoApp.WriteLine($"Compatibility test for {Path.GetFileNameWithoutExtension(path)} {(result ? "succeeded" : "failed")} in {time.TotalSeconds:0.00}s"); - if (!result) { + RhinoApp.WriteLine($"Compatibility test for {Path.GetFileNameWithoutExtension(path)} failed in {time.TotalSeconds:0.00}s"); + var outputDir = Path.Combine(Path.GetTempPath(), "RhinoCompat"); if (!Directory.Exists(outputDir)) Directory.CreateDirectory(outputDir); diff --git a/src/librhino3dm_native/on_nurbscurve.cpp b/src/librhino3dm_native/on_nurbscurve.cpp index 69155efe9..a4f475529 100644 --- a/src/librhino3dm_native/on_nurbscurve.cpp +++ b/src/librhino3dm_native/on_nurbscurve.cpp @@ -40,6 +40,7 @@ RH_C_FUNCTION bool ON_NurbsCurve_CreatePeriodicUniformNurbs(ON_NurbsCurve* crv, return false; return crv->CreatePeriodicUniformNurbs(dim, order, count, pts, knot_delta); } + #if !defined(RHINO3DM_BUILD) RH_C_FUNCTION ON_NurbsCurve* ON_NurbsCurve_CreateControlPointCurve(int count, /*ARRAY*/const ON_3dPoint* points, int degree) { @@ -93,6 +94,7 @@ RH_C_FUNCTION ON_NurbsCurve* ON_NurbsCurve_CreateControlPointCurve(int count, /* return pNC; } #endif + RH_C_FUNCTION bool ON_NurbsCurve_GetBool(ON_NurbsCurve* pCurve, int which) { const int idxIsRational = 0; diff --git a/src/librhino3dm_native/on_planesurface.cpp b/src/librhino3dm_native/on_planesurface.cpp index 8719f0d62..c387c8411 100644 --- a/src/librhino3dm_native/on_planesurface.cpp +++ b/src/librhino3dm_native/on_planesurface.cpp @@ -69,8 +69,6 @@ RH_C_FUNCTION void ON_PlaneSurface_SetPlane(ON_PlaneSurface* pPlaneSurface, cons } } -#if !defined(RHINO3DM_BUILD) - RH_C_FUNCTION void ON_PlaneSurface_GetExtents(const ON_PlaneSurface* pPlaneSurface, int direction, ON_Interval* pExtents) { if (pPlaneSurface && pExtents) @@ -89,7 +87,6 @@ RH_C_FUNCTION void ON_PlaneSurface_SetExtents(ON_PlaneSurface* pPlaneSurface, in pPlaneSurface->SetExtents(direction, *pExtents, bSyncDomain); } } -#endif RH_C_FUNCTION ON_Mesh* ON_PlaneSurface_CreateMesh(const ON_PlaneSurface* pPlaneSurface) { diff --git a/src/librhino3dm_native/rhcommon_c/rhcommon_c_api.h b/src/librhino3dm_native/rhcommon_c/rhcommon_c_api.h index 6bd0db715..2ede0299c 100644 --- a/src/librhino3dm_native/rhcommon_c/rhcommon_c_api.h +++ b/src/librhino3dm_native/rhcommon_c/rhcommon_c_api.h @@ -81,7 +81,11 @@ const wchar_t* _variablename = _parametername; #if !defined (RHINO3DM_BUILD) #if defined (__APPLE__) typedef CGImageRef HBITMAP_OR_CGIMAGE; +#if defined (ON_RUNTIME_APPLE_IOS) +typedef UIImage* HBITMAP_OR_NSIMAGE; +#else typedef NSImage* HBITMAP_OR_NSIMAGE; +#endif #else typedef HBITMAP HBITMAP_OR_CGIMAGE; typedef HBITMAP HBITMAP_OR_NSIMAGE; @@ -274,3 +278,7 @@ static const ON_SHA1_Hash* ON_SHA1_Hash_From_Array_Reinterpret(const unsigned ch #else #define RHCHECK_LICENSE RhCheckLicenseAndThrow(true); #endif + +#if !defined(RHINO_CLAMP) +#define RHINO_CLAMP(V,L,H) ( (V) < (L) ? (L) : ( (V) > (H) ? (H) : (V) ) ) +#endif diff --git a/tests/SampleCSAddGroup/Program.cs b/tests/SampleCSAddGroup/Program.cs new file mode 100644 index 000000000..02a980907 --- /dev/null +++ b/tests/SampleCSAddGroup/Program.cs @@ -0,0 +1,33 @@ +using System; +using Rhino; +using Rhino.Geometry; + +string pathThis = typeof(Program).Assembly.Location; +int rhino3dmIndex = pathThis.IndexOf("rhino3dm"); +string pathLibRhino3dm = pathThis.Substring(0, rhino3dmIndex); +pathLibRhino3dm += "rhino3dm\\src\\build\\windows\\win64\\Debug\\librhino3dm_native.dll"; + +Console.WriteLine("Path to native lib: {0}", pathLibRhino3dm); + +// Force load librhino3dm +nint handleLibRhino3dm = System.Runtime.InteropServices.NativeLibrary.Load(pathLibRhino3dm); + +var doc = new Rhino.FileIO.File3dm(); +var index = doc.AllGroups.AddGroup(); +Console.WriteLine("nº of groups {0}",doc.AllGroups.Count); + +for( int i = 1; i < 10; i ++ ) { + var circle = new Rhino.Geometry.Circle(i); + var id = doc.Objects.AddCircle(circle); + var ro = doc.Objects.FindId(id); + ro.Attributes.AddToGroup(index); + Console.WriteLine("Group Count: {0}", ro.Attributes.GroupCount); + Console.WriteLine("Group List: {0}",ro.Attributes.GetGroupList()); +} + +var tmpPath = System.IO.Path.GetTempPath(); +tmpPath = System.IO.Path.Combine(tmpPath, "testGroup.3dm"); + +doc.Write(tmpPath, 8); +Console.WriteLine(tmpPath); + diff --git a/tests/SampleCSAddGroup/SampleCSAddGroup.csproj b/tests/SampleCSAddGroup/SampleCSAddGroup.csproj new file mode 100644 index 000000000..6735dbe32 --- /dev/null +++ b/tests/SampleCSAddGroup/SampleCSAddGroup.csproj @@ -0,0 +1,19 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + diff --git a/tests/SampleCSAddGroup/SampleCSAddGroup.sln b/tests/SampleCSAddGroup/SampleCSAddGroup.sln new file mode 100644 index 000000000..4625e55a3 --- /dev/null +++ b/tests/SampleCSAddGroup/SampleCSAddGroup.sln @@ -0,0 +1,76 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleCSAddGroup", "SampleCSAddGroup.csproj", "{102D5018-9DC5-4625-96E3-55B984B06B10}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rhino3dm", "..\..\src\dotnet\Rhino3dm.csproj", "{C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librhino3dm_native", "..\..\src\build\windows\win64\librhino3dm_native.vcxproj", "{30DE87D8-E643-39B4-A371-80D280BB799D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + MinSizeRel|Any CPU = MinSizeRel|Any CPU + MinSizeRel|x64 = MinSizeRel|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + RelWithDebInfo|Any CPU = RelWithDebInfo|Any CPU + RelWithDebInfo|x64 = RelWithDebInfo|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {102D5018-9DC5-4625-96E3-55B984B06B10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.Debug|Any CPU.Build.0 = Debug|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.Debug|x64.ActiveCfg = Debug|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.Debug|x64.Build.0 = Debug|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.MinSizeRel|x64.ActiveCfg = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.MinSizeRel|x64.Build.0 = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.Release|Any CPU.ActiveCfg = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.Release|Any CPU.Build.0 = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.Release|x64.ActiveCfg = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.Release|x64.Build.0 = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {102D5018-9DC5-4625-96E3-55B984B06B10}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.Debug|x64.ActiveCfg = Debug|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.Debug|x64.Build.0 = Debug|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.Release|Any CPU.Build.0 = Release|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.Release|x64.ActiveCfg = Release|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.Release|x64.Build.0 = Release|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {C93704EB-B09F-46C4-8C4A-9A1EB19A2EF1}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {30DE87D8-E643-39B4-A371-80D280BB799D}.Debug|Any CPU.ActiveCfg = Debug|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.Debug|Any CPU.Build.0 = Debug|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.Debug|x64.ActiveCfg = Debug|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.Debug|x64.Build.0 = Debug|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.MinSizeRel|x64.Build.0 = MinSizeRel|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.Release|Any CPU.ActiveCfg = Release|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.Release|Any CPU.Build.0 = Release|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.Release|x64.ActiveCfg = Release|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.Release|x64.Build.0 = Release|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 + {30DE87D8-E643-39B4-A371-80D280BB799D}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal