Skip to content

Commit

Permalink
Merge pull request #652 from StudioWEngineers/support_negative_indexing
Browse files Browse the repository at this point in the history
[Python] Add support for negative indexing in ObjectTable
  • Loading branch information
fraguada authored Nov 5, 2024
2 parents 162d489 + 9db22e9 commit 59dc784
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
30 changes: 16 additions & 14 deletions src/bindings/bnd_extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ static bool SeekPastCompressedBuffer(ON_BinaryArchive& archive)
size_t sizeof__outbuffer;
if (!archive.ReadCompressedBufferSize(&sizeof__outbuffer))
return false;

if (0 == sizeof__outbuffer)
return true;

Expand Down Expand Up @@ -464,13 +464,13 @@ BND_UUID BND_ONXModel_ObjectTable::AddPolyline2(const std::vector<ON_3dPoint>& p
BND_UUID BND_ONXModel_ObjectTable::AddPolyline3(emscripten::val points, const class BND_3dmObjectAttributes* attributes)
{
bool isArray = points.hasOwnProperty("length");
if( isArray )
if( isArray )
{
const std::vector<ON_3dPoint> array = emscripten::vecFromJSArray<ON_3dPoint>(points);
return AddPolyline2( array, attributes );
return AddPolyline2( array, attributes );
}
else
return AddPolyline1( points.as<const BND_Point3dList&>(), attributes );
return AddPolyline1( points.as<const BND_Point3dList&>(), attributes );
}

#endif
Expand Down Expand Up @@ -669,10 +669,7 @@ static BND_FileObject* FileObjectFromCompRef(ON_ModelComponentReference& compref

BND_FileObject* BND_ONXModel_ObjectTable::ModelObjectAt(int index)
{
#if defined(ON_PYTHON_COMPILE)
if (index < 0)
throw py::index_error();
#else
#if !defined(ON_PYTHON_COMPILE)
if (index < 0)
return nullptr;
#endif
Expand Down Expand Up @@ -700,6 +697,11 @@ BND_FileObject* BND_ONXModel_ObjectTable::ModelObjectAt(int index)
}
}

#if defined(ON_PYTHON_COMPILE)
if (index < 0)
index = m_compref_cache.Count() + index < 0 ? std::abs(index) : m_compref_cache.Count() + index;
#endif

if (index < m_compref_cache.Count())
{
return FileObjectFromCompRef(m_compref_cache[index]);
Expand Down Expand Up @@ -1217,7 +1219,7 @@ int BND_File3dmInstanceDefinitionTable::Add(std::wstring name, std::wstring desc
const int count_a = attributes["length"].as<int>();
#endif

if(m_model && count_g > 0)
if(m_model && count_g > 0)
{
// Determine if we need to transform geometry to world origin
ON_Xform xf;
Expand All @@ -1230,17 +1232,17 @@ int BND_File3dmInstanceDefinitionTable::Add(std::wstring name, std::wstring desc

ON_SimpleArray<ON_UUID> object_uuids;

for ( int i = 0; i < count_g; i ++ )
for ( int i = 0; i < count_g; i ++ )
{

#if defined(ON_PYTHON_COMPILE)
BND_GeometryBase g = py::cast<BND_GeometryBase>(geometry[i]);
BND_3dmObjectAttributes oa = py::cast<BND_3dmObjectAttributes>(attributes[i]);
#else
BND_GeometryBase g = geometry[i].as<BND_GeometryBase>();
BND_GeometryBase g = geometry[i].as<BND_GeometryBase>();
BND_3dmObjectAttributes oa = attributes[i].as<BND_3dmObjectAttributes>();
#endif

const ON_Geometry* pConstGeom = g.GeometryPointer();
const ON_3dmObjectAttributes* pConstAtts = i < count_a ? oa.m_attributes : &ON_3dmObjectAttributes::DefaultAttributes;

Expand Down Expand Up @@ -1302,7 +1304,7 @@ int BND_File3dmInstanceDefinitionTable::Add(std::wstring name, std::wstring desc
}
}
}

return index;
}

Expand Down Expand Up @@ -1614,7 +1616,7 @@ BND_TUPLE BND_FileObject::GetTextureMapping( const class BND_File3dm* file3dm, i
if(tm == ON_TextureMapping::Unset)
return NullTuple();
else
else
{
SetTuple(rc, 0, BND_TextureMapping(tm, nullptr));
SetTuple(rc, 1, BND_Transform(m_object_xform));
Expand Down
23 changes: 22 additions & 1 deletion tests/python/test_File3dm_ObjectTable.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,28 @@ def test_addPolyline(self):

self.assertTrue(objqty == 2 and isCurve1 and isCurve2 and len1 == 15 and len2 == 15)


def test_negativeIndexing(self) -> None:
"""Tests for indexing `ObjectTable`.
"""
file_3dm = rhino3dm.File3dm()
for i in range(2):
file_3dm.Objects.AddPoint(rhino3dm.Point3d(i, i, i))

with self.assertRaises(IndexError, msg="Test negative IndexError"):
file_3dm.Objects[-3]

with self.assertRaises(IndexError, msg="Test positive IndexError"):
file_3dm.Objects[3]

with self.subTest(msg="Test positive indexing"):
self.assertEqual(file_3dm.Objects[1].Geometry.Location, rhino3dm.Point3d(1, 1, 1))

with self.subTest(msg="Test negative indexing"):
self.assertEqual(file_3dm.Objects[-2].Geometry.Location, rhino3dm.Point3d(0, 0, 0))


if __name__ == '__main__':
print("running tests")
unittest.main()
print("tests complete")
print("tests complete")

0 comments on commit 59dc784

Please sign in to comment.