Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Python] Add support for negative indexing in ObjectTable #652

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")