Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/mcneel/rhino3dm into luis/ad…
Browse files Browse the repository at this point in the history
…dMaterial

# Conflicts:
#	src/librhino3dm_native/on_archive.cpp
  • Loading branch information
fraguada committed Dec 19, 2023
2 parents 2b61bcf + 79d1dcb commit 5e994e3
Show file tree
Hide file tree
Showing 23 changed files with 411 additions and 42 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,5 @@ node_modules/
bin/
obj/
x64/
Properties/
*.3dm
9 changes: 9 additions & 0 deletions src/bindings/bnd_extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -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())
Expand Down
1 change: 1 addition & 0 deletions src/bindings/bnd_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class BND_ONXModel_ObjectTable
//Guid AddLeader4(string text, Plane plane, IEnumerable<Point2d> 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<Guid> objectIds)
Expand Down
6 changes: 6 additions & 0 deletions src/dotnet/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,9 @@
"341a3109b0528c9775fe5b46bfc85ecb90e75f265bef0700eb98176671b4ff9c7e74ac683ebe8d" +
"50cd4a1c4538d6bf94a7c7c48da9fee90327e273fbc0208c76f6782220d290dee6067981d33ea4" +
"a3b345cf")]

[assembly: InternalsVisibleTo("Export_DAE, PublicKey=002400000480000094000000060200000024000052534131000400000100010083c66ae8bfbbea" +
"010a18559b1502c1b79e1fbb74b62ea03fec9bd46ec6fec5c1917c8a92c44f96a449f87cce288e" +
"341a3109b0528c9775fe5b46bfc85ecb90e75f265bef0700eb98176671b4ff9c7e74ac683ebe8d" +
"50cd4a1c4538d6bf94a7c7c48da9fee90327e273fbc0208c76f6782220d290dee6067981d33ea4" +
"a3b345cf")]
5 changes: 3 additions & 2 deletions src/dotnet/hostutils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 3 additions & 4 deletions src/dotnet/opennurbs/opennurbs_beam.cs
Original file line number Diff line number Diff line change
Expand Up @@ -606,16 +606,15 @@ public Mesh GetMesh(MeshType meshType)
/// </summary>
/// <param name="mesh">The mesh.</param>
/// <param name="meshType">The mesh type.</param>
/// <returns>A bool.</returns>
[ConstOperation]
/// <returns>True on success.</returns>
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;
}
Expand Down
42 changes: 41 additions & 1 deletion src/dotnet/opennurbs/opennurbs_extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1423,6 +1423,16 @@ public File3dmWriteOptions()
/// <since>5.9</since>
public int Version { get; set; }

internal int File3dmValidVersion
{
get
{
int version = Version;
if (version >= 5 && version < 50)
version *= 10;
return version;
}
}
/// <summary>
/// Include Render meshes in the file. Default is true
/// </summary>
Expand Down Expand Up @@ -1692,6 +1702,7 @@ public abstract class CommonComponentTable<T> :
where T : ModelComponent
{
internal ManifestTable m_manifest;
internal bool _nonIndexedTable = false;

internal CommonComponentTable(ManifestTable manifest)
{
Expand Down Expand Up @@ -1770,6 +1781,34 @@ public virtual T FindId(Guid id)
/// </summary>
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<T>, but it is. The current .Net implementations of First() and
// Last() check for Ilist<T> 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<T> and Last<T> functions here because they check to see if this class
// implements IList<T>, 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<T> e = GetEnumerator())
{
int i = index;
while (i-- >= 0)
{
if (!e.MoveNext()) return null;
}
return (T)e.Current;
}
}
return (T)m_manifest.FindIndex(index, ComponentType);
}

Expand Down Expand Up @@ -4132,6 +4171,7 @@ public File3dmObject[] GroupMembers(int groupIndex)
/// Adds a new empty group to the group table.
/// </summary>
/// <returns>>=0 index of new group or -1 on error.</returns>
/// <sice>8.4</since>
public int AddGroup() {

IntPtr ptrFile3dm = m_parent.NonConstPointer();
Expand Down
2 changes: 0 additions & 2 deletions src/dotnet/opennurbs/opennurbs_nurbssurface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
/// <summary>
/// Gets the style of the knot vector.
/// </summary>
Expand All @@ -1870,7 +1869,6 @@ public KnotStyle KnotStyle
return (KnotStyle)UnsafeNativeMethods.ON_NurbsSurface_KnotStyle(const_ptr_surface, m_direction);
}
}
#endif //RHINO_SDK

/// <summary>
/// Gets or sets the knot vector value at the given index.
Expand Down
4 changes: 2 additions & 2 deletions src/dotnet/opennurbs/opennurbs_object.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 0 additions & 2 deletions src/dotnet/opennurbs/opennurbs_planesurface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public Plane Plane
}
}

#if RHINO_SDK
/// <summary>
/// Gets the extents of the plane surface.
/// </summary>
Expand Down Expand Up @@ -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

/// <summary>
/// Computes a polygon mesh of the surface made of one quad.
Expand Down
121 changes: 121 additions & 0 deletions src/dotnet/opennurbs/opennurbs_subd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,127 @@ public static SubD CreateFromSurface(Surface surface, SubDFromSurfaceMethods met
return null;
}

#if RHINO_SDK

/// <summary>
/// Creates a SubD sphere made from quad faces.
/// </summary>
/// <param name="sphere">Location, size and orientation of the sphere.</param>
/// <param name="vertexLocation">
/// 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.
/// </param>
/// <param name="quadSubdivisionLevel">
/// The resulting sphere will have 6*4^subdivision level quads.
/// (0 for 6 quads, 1 for 24 quads, 2 for 96 quads, ...).
/// </param>
/// <returns>
/// If the input parameters are valid, a SubD quad sphere is returned. Otherwise null is returned.
/// </returns>
/// <since>8.4</since>
[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;
}

/// <summary>
/// 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.
/// </summary>
/// <param name="sphere">Location, size and orientation of the sphere.</param>
/// <param name="vertexLocation">
/// 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.
/// </param>
/// <param name="axialFaceCount">
/// Number of faces along the sphere's meridians. (axialFaceCount &gt;= 2)
/// For example, if you wanted each face to span 30 degrees of latitude,
/// you would pass 6 (=180 degrees/30 degrees) for axialFaceCount.
/// </param>
/// <param name="equatorialFaceCount">
/// Number of faces around the sphere's parallels. (equatorialFaceCount &gt;= 3)
/// For example, if you wanted each face to span 30 degrees of longitude,
/// you would pass 12 (=360 degrees/30 degrees) for equatorialFaceCount.
/// </param>
/// <returns>
/// If the input parameters are valid, a SubD globe sphere is returned. Otherwise null is returned.
/// </returns>
/// <since>8.4</since>
[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;
}

/// <summary>
/// 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().
/// </summary>
/// <param name="sphere">Location, size and orientation of the sphere.</param>
/// <param name="vertexLocation">
/// 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.
/// </param>
/// <param name="triSubdivisionLevel">
/// The resulting sphere will have 20*4^subdivision level triangles.
/// (0 for 20 triangles, 1 for 80 triangles, 2 for 320 triangles, ...).
/// </param>
/// <returns>
/// If the input parameters are valid, a SubD tri sphere is returned. Otherwise null is returned.
/// </returns>
/// <since>8.4</since>
[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;
}

/// <summary>
/// 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().
/// </summary>
/// <param name="sphere">Location, size and orientation of the sphere.</param>
/// <param name="vertexLocation">
/// 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.
/// </param>
/// <returns>
/// If the input parameters are valid, a SubD icosahedron is returned. Otherwise null is returned.
/// </returns>
/// <since>8.4</since>
[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

/// <summary>
/// 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.
Expand Down
24 changes: 24 additions & 0 deletions src/dotnet/rhino/rhinosdkdisplaypipelineattributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,30 @@ public bool ShowPointClouds
get { return GetBool(UnsafeNativeMethods.DisplayPipelineAttributesBool.ShowPointClouds); }
set { SetBool(UnsafeNativeMethods.DisplayPipelineAttributesBool.ShowPointClouds, value); }
}

/// <since>8.4</since>
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);
}
}

/// <since>8.4</since>
public float PointCloudRadius
{
get { return GetInt(UnsafeNativeMethods.DisplayAttributesInt.PointCloudSize); }
set { SetInt(UnsafeNativeMethods.DisplayAttributesInt.PointCloudSize, (int)value); }
}
#endregion


Expand Down
2 changes: 1 addition & 1 deletion src/dotnet/rhino/rhinosdkdoc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5634,7 +5634,7 @@ public sealed class ObjectTable :
RhinoDocCommonTable<RhinoObject>,
ICollection<RhinoObject>
{
internal ObjectTable(RhinoDoc doc) : base(doc){}
internal ObjectTable(RhinoDoc doc) : base(doc){ _nonIndexedTable = true; }

/// <summary>
/// Gets the document that owns this object table.
Expand Down
Loading

0 comments on commit 5e994e3

Please sign in to comment.